

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/fluid.png">
  <link rel="icon" href="/img/fluid.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="John Doe">
  <meta name="keywords" content="">
  
    <meta name="description" content="TypeScript基础">
<meta property="og:type" content="article">
<meta property="og:title" content="TypeScript">
<meta property="og:url" content="http://example.com/2023/06/25/TypeScript/index.html">
<meta property="og:site_name" content="晕晕晕晕晕">
<meta property="og:description" content="TypeScript基础">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://example.com/img/x6pl9v.jpg">
<meta property="article:published_time" content="2023-06-25T01:41:28.000Z">
<meta property="article:modified_time" content="2023-06-25T03:20:36.747Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="http://example.com/img/x6pl9v.jpg">
  
  
  
  <title>TypeScript - 晕晕晕晕晕</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"example.com","root":"/","version":"1.9.4","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
  


  
<meta name="generator" content="Hexo 6.3.0"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>晕晕晕晕晕</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                <span>首页</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                <span>归档</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                <span>分类</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                <span>标签</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                <span>关于</span>
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              <i class="iconfont icon-search"></i>
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">
              <i class="iconfont icon-dark" id="color-toggle-icon"></i>
            </a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/img/wall.png') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="TypeScript"></span>
          
        </div>

        
          
  <div class="mt-3">
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2023-06-25 09:41" pubdate>
          2023年6月25日 上午
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          37k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          307 分钟
        
      </span>
    

    
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">TypeScript</h1>
            
            
              <div class="markdown-body">
                
                <h3 id="1-TypeScript-概述"><a href="#1-TypeScript-概述" class="headerlink" title="1. TypeScript 概述"></a>1. TypeScript 概述</h3><h4 id="1-1-TypeScript-是什么"><a href="#1-1-TypeScript-是什么" class="headerlink" title="1.1 TypeScript 是什么"></a>1.1 TypeScript 是什么</h4><p>TypeScript 是一门基于 JavaScript 的编程语言，它是具有类型系统的 JavaScript，是一种解决 JavaScript 缺点的编程语言。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 所有的 JavaScript 代码都是合法的 TypeScript 代码。</span><br><span class="hljs-keyword">var</span> a = <span class="hljs-number">10</span>;<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) &#123;&#125;<br><span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) &#123;<br>&#125;<br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; i++) &#123;&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// TypeScript 是静态类型编程语言，即编译期间进行类型检查，变量、参数、返回值等都必须有固定的类型。</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">x</span>: <span class="hljs-built_in">number</span> = <span class="hljs-number">10</span>;<br>x = <span class="hljs-number">20</span>; <span class="hljs-comment">// ✅</span><br>x = <span class="hljs-string">&quot;a&quot;</span>; <span class="hljs-comment">// ❎</span><br></code></pre></td></tr></table></figure>

<h4 id="1-2-类型系统带来的好处"><a href="#1-2-类型系统带来的好处" class="headerlink" title="1.2 类型系统带来的好处"></a>1.2 类型系统带来的好处</h4><p>通过静态类型检查可以让开发者在编译时就能发现错误而不是在代码运行时。</p>
<p>类型系统为编辑器带来了更加精准的代码提示，以此来提升开发人员的编程体验。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript">app.<span class="hljs-title function_">get</span>(<span class="hljs-string">&quot;/&quot;</span>, <span class="hljs-keyword">function</span> (<span class="hljs-params">req, res</span>) &#123;<br>  res.<span class="hljs-property">send</span>;<br>  sendDate;<br>  sendfile;<br>  sendFile;<br>  sendStatus;<br>&#125;);<br></code></pre></td></tr></table></figure>

<p>在声明变量时明确告知编译器它的类型，编译器就知道该变量可以调用哪些属性和方法，当开发者调用了错误的属性或方法时，编译器会及时给出提示。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">var</span> <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span> = <span class="hljs-string">&quot;张三&quot;</span>;<br>name.<span class="hljs-title function_">toFixed</span>(<span class="hljs-number">2</span>); <span class="hljs-comment">// 属性&quot;toFixed&quot;在类型&quot;string&quot;上不存在</span><br></code></pre></td></tr></table></figure>

<p>在声明函数时明确告知编译器参数的类型，当开发者调用该函数时如果传递的参数的类型不正确，编译器会及时给出提示。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">sum</span>(<span class="hljs-params">x: <span class="hljs-built_in">number</span>, y: <span class="hljs-built_in">number</span></span>) &#123;&#125;<br><span class="hljs-title function_">sum</span>(<span class="hljs-number">10</span>, <span class="hljs-string">&quot;a&quot;</span>); <span class="hljs-comment">// 类型&quot;string&quot;的参数不能赋给类型&quot;number&quot;的参数。</span><br></code></pre></td></tr></table></figure>

<p>在声明函数时明确告知编译器返回值的类型，当开发者返回的值的类型错误时，编译器会及时给出提示。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">sayHello</span>(<span class="hljs-params"></span>): <span class="hljs-built_in">string</span> &#123;<br>  <span class="hljs-keyword">return</span> <span class="hljs-number">100</span>; <span class="hljs-comment">// 不能将类型&quot;number&quot;分配给类型&quot;string&quot;。</span><br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="2-TypeScript-初体验"><a href="#2-TypeScript-初体验" class="headerlink" title="2. TypeScript 初体验"></a>2. TypeScript 初体验</h3><h4 id="2-1-第一个-TypeScript-应用"><a href="#2-1-第一个-TypeScript-应用" class="headerlink" title="2.1 第一个 TypeScript 应用"></a>2.1 第一个 TypeScript 应用</h4><ul>
<li><input disabled type="checkbox"> 安装 TypeScript 编译器，用于将 TypeScript 代码编译为 JavaScript 代码</li>
<li><input disabled type="checkbox"> 安装 axios 库，用于发送请求</li>
<li><input disabled type="checkbox"> 新建 index.ts 文件，用于编写代码</li>
<li><input disabled type="checkbox"> 将 TypeScript 代码编译为 JavaScript 代码并执行</li>
</ul>
<p>第一步：安装 TypeScript 编译器，用于将 TypeScript 代码编译为 JavaScript 代码</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 全局安装 typescript 编译器</span><br>npm install -g typescript<br><span class="hljs-comment"># 通过查看 typescript 编译器版本验证编译器是否安装成功</span><br>tsc -version<br></code></pre></td></tr></table></figure>

<p>第二步：安装 axios 库，用于发送请求。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 安装 axios 用于发送请求</span><br>npm install axios<br></code></pre></td></tr></table></figure>

<p>第三步：新建 index.ts 文件用于编写代码，TypeScript 程序文件的后缀名为 <code>.ts</code>。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs bash">import axios from <span class="hljs-string">&quot;axios&quot;</span>;<br><br>axios.get(<span class="hljs-string">&quot;https://jsonplaceholder.typicode.com/todos/1&quot;</span>).<span class="hljs-keyword">then</span>((response) =&gt; &#123;<br>  console.log(response.data);<br>&#125;);<br></code></pre></td></tr></table></figure>

<p>第四步：将 TypeScript 代码编译为 JavaScript 代码并执行。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 编译 index.ts 文件, 编译后在同级目录下会多出 index.js 文件, 该文件存储的就是编译后的 JavaScript 代码</span><br>tsc index.ts<br><span class="hljs-comment"># 执行 JavaScript 代码</span><br>node index.js<br></code></pre></td></tr></table></figure>

<h4 id="2-2-优化工作流"><a href="#2-2-优化工作流" class="headerlink" title="2.2 优化工作流"></a>2.2 优化工作流</h4><p>目标：监控 TypeScript 文件的变化，实现自动编译、自动执行代码</p>
<ul>
<li><p><input disabled type="checkbox"> 
安装 nodemon、ts-node</p>
</li>
<li><p><input disabled type="checkbox"> 
创建应用启动脚本</p>
</li>
<li><p><input disabled type="checkbox"> 
通过应用启动脚本启动应用</p>
</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># nodemon: 监听文件的变化, 当 TypeScript 文件内容发生变动后调用 ts-node</span><br><span class="hljs-comment"># ts-node: 将 TypeScript 编译为 JavaScript 并执行</span><br>npm install -g nodemon ts-node<br></code></pre></td></tr></table></figure>

<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash">// package.json<br><span class="hljs-string">&quot;scripts&quot;</span>: &#123;<br>  <span class="hljs-string">&quot;start&quot;</span>: <span class="hljs-string">&quot;nodemon index.ts&quot;</span><br>&#125;,<br></code></pre></td></tr></table></figure>

<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm start<br></code></pre></td></tr></table></figure>

<p>tsc 与 ts-node 的主要区别在于 tsc 根据 tsconfig 编译所有文件，ts-node 会从入口文件开始，并根据模块关系逐步转译文件。</p>
<h3 id="3-TypeScript-基础类型"><a href="#3-TypeScript-基础类型" class="headerlink" title="3. TypeScript 基础类型"></a>3. TypeScript 基础类型</h3><h4 id="3-1-概述"><a href="#3-1-概述" class="headerlink" title="3.1 概述"></a>3.1 概述</h4><p>以下表格中列出的所有类型在 TypeScript 中都是支持的。</p>
<table>
<thead>
<tr>
<th>JavaScript</th>
<th>Typescript</th>
</tr>
</thead>
<tbody><tr>
<td>number</td>
<td>any</td>
</tr>
<tr>
<td>string</td>
<td>unknow</td>
</tr>
<tr>
<td>boolean</td>
<td>never</td>
</tr>
<tr>
<td>null</td>
<td>enum</td>
</tr>
<tr>
<td>undefined</td>
<td>tuple</td>
</tr>
<tr>
<td>object</td>
<td></td>
</tr>
</tbody></table>
<h4 id="3-2-基本数据类型"><a href="#3-2-基本数据类型" class="headerlink" title="3.2 基本数据类型"></a>3.2 基本数据类型</h4><p>在 TypeScript 中，开发者可以通过类型注释对变量的类型进行标注。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 数值类型</span><br><span class="hljs-comment">// :number 类型注释</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">apples</span>: <span class="hljs-built_in">number</span> = <span class="hljs-number">5</span>;<br><span class="hljs-comment">// 字符串类型</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">speed</span>: <span class="hljs-built_in">string</span> = <span class="hljs-string">&quot;fast&quot;</span>;<br><span class="hljs-comment">// 布尔值布尔</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">hasName</span>: <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">true</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// TS2322: Type &#x27;string&#x27; is not assignable to type &#x27;number&#x27;</span><br><span class="hljs-comment">// 类型 &#x27;string&#x27; 不能分配给类型 &#x27;number&#x27;</span><br>apples = <span class="hljs-string">&quot;5&quot;</span>; <span class="hljs-comment">// ❎</span><br><br><span class="hljs-comment">// TS2322: Type &#x27;number&#x27; is not assignable to type &#x27;string&#x27;.</span><br><span class="hljs-comment">// 类型 &#x27;number&#x27; 不能分配给类型 &#x27;string&#x27;</span><br>speed = <span class="hljs-number">120</span>; <span class="hljs-comment">// ❎</span><br><br><span class="hljs-comment">// TS2322: Type &#x27;string&#x27; is not assignable to type &#x27;boolean&#x27;.</span><br><span class="hljs-comment">// 类型 &#x27;string&#x27; 不能分类给类型 &#x27;boolean&#x27;</span><br>hasName = <span class="hljs-string">&quot;yes&quot;</span>; <span class="hljs-comment">// ❎</span><br></code></pre></td></tr></table></figure>

<p><img src="/2023/06/25/TypeScript/ts1.jpg" srcset="/img/loading.gif" lazyload></p>
<h4 id="3-3-any-类型"><a href="#3-3-any-类型" class="headerlink" title="3.3 any 类型"></a>3.3 any 类型</h4><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// any 类型</span><br><span class="hljs-comment">// 变量中可以存储任何数据类型的值</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">anything</span>: <span class="hljs-built_in">any</span> = <span class="hljs-string">&quot;Hello TypeScript&quot;</span>;<br>anything = <span class="hljs-literal">true</span>; <span class="hljs-comment">// ✅</span><br>anything = <span class="hljs-number">3.14</span>; <span class="hljs-comment">// ✅</span><br>anything = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;&#125;; <span class="hljs-comment">// ✅</span><br>anything = <span class="hljs-literal">null</span>; <span class="hljs-comment">// ✅</span><br></code></pre></td></tr></table></figure>

<h4 id="3-4-数组-Array"><a href="#3-4-数组-Array" class="headerlink" title="3.4 数组 Array"></a>3.4 数组 Array</h4><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 在没有为数组变量标注类型时, 变量的初始值又是一个空数组</span><br><span class="hljs-comment">// 此时该数组中可以存储任何类型的值</span><br><span class="hljs-comment">// 虽然写法正确, 但丢失了 TypeScript 类型检查功能</span><br><span class="hljs-comment">// let colors = never[];</span><br><span class="hljs-keyword">let</span> colors = [];<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 字符串数组</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">colors</span>: <span class="hljs-built_in">string</span>[] = [<span class="hljs-string">&quot;red&quot;</span>, <span class="hljs-string">&quot;green&quot;</span>, <span class="hljs-string">&quot;blue&quot;</span>];<br><span class="hljs-comment">// 数值数组</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">numbers</span>: <span class="hljs-built_in">number</span>[] = [<span class="hljs-number">100</span>, <span class="hljs-number">200</span>, <span class="hljs-number">300</span>];<br><span class="hljs-comment">// 布尔数组</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">bools</span>: <span class="hljs-built_in">boolean</span>[] = [<span class="hljs-literal">true</span>, <span class="hljs-literal">true</span>, <span class="hljs-literal">false</span>];<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 二维数组</span><br><span class="hljs-keyword">const</span> <span class="hljs-attr">carMakers</span>: <span class="hljs-built_in">string</span>[][] = [[<span class="hljs-string">&quot;宝马&quot;</span>, <span class="hljs-string">&quot;比亚迪&quot;</span>]];<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// let colors: string[]</span><br><span class="hljs-comment">// item: string</span><br>colors.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> &#123;&#125;);<br><span class="hljs-comment">// a: string</span><br><span class="hljs-keyword">let</span> a = colors[<span class="hljs-number">0</span>];<br></code></pre></td></tr></table></figure>

<h4 id="3-5-元组-Tuples"><a href="#3-5-元组-Tuples" class="headerlink" title="3.5 元组 Tuples"></a>3.5 元组 Tuples</h4><p>元组可以按照顺序约束数组中每个下标对应的数据的类型。</p>
<p>[string, number, boolean] &#x3D;&gt; [“a”, 100, false]</p>
<p>观察下列代码中存在的问题。</p>
<p>在 employee 数组中我们约定下标为 0 的位置存储员工姓名，下标为 1 的位置存储员工的年龄。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> employee = [<span class="hljs-string">&quot;张三&quot;</span>, <span class="hljs-number">20</span>];<br>employee[<span class="hljs-number">0</span>] = <span class="hljs-number">30</span>;<br>employee[<span class="hljs-number">1</span>] = <span class="hljs-string">&quot;李四&quot;</span>;<br></code></pre></td></tr></table></figure>

<p>以上代码中存在的问题是 employee 数组中的元素没有被类型系统约束，导致在修改元素时没有任何错误提示。</p>
<p>元组是 TypeScript 引入的一种新数据类型，它像数组一样工作但是有一些额外的限制：元组中元素个数是固定，元组中元素类型已知。</p>
<p>元组用来存储一些以特定顺序出现且相关联的数据，通过元组可以约束元素个数及元素类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">const</span> <span class="hljs-attr">employee</span>: [<span class="hljs-built_in">string</span>, <span class="hljs-built_in">number</span>] = [<span class="hljs-string">&quot;张三&quot;</span>, <span class="hljs-number">20</span>];<br><span class="hljs-comment">// 不能将类型&quot;number&quot;分配给类型&quot;string&quot;</span><br>employee[<span class="hljs-number">0</span>] = <span class="hljs-number">30</span>;<br><span class="hljs-comment">// 不能将类型&quot;string&quot;分配给类型&quot;number&quot;</span><br>employee[<span class="hljs-number">1</span>] = <span class="hljs-string">&quot;李四&quot;</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 使用元组存储 RGB 颜色值及透明度</span><br><span class="hljs-keyword">var</span> <span class="hljs-attr">bgColor</span>: [<span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>] = [<span class="hljs-number">0</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.5</span>];<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 创建元组数组(二维数组)</span><br><span class="hljs-keyword">var</span> <span class="hljs-attr">employees</span>: [<span class="hljs-built_in">number</span>, <span class="hljs-built_in">string</span>][] = [<br>  [<span class="hljs-number">1</span>, <span class="hljs-string">&quot;Steve&quot;</span>],<br>  [<span class="hljs-number">2</span>, <span class="hljs-string">&quot;Tom&quot;</span>],<br>];<br></code></pre></td></tr></table></figure>

<h4 id="3-6-枚举-Enum"><a href="#3-6-枚举-Enum" class="headerlink" title="3.6 枚举 Enum"></a>3.6 枚举 Enum</h4><p>枚举用于存储一组密切相关且有限的值，可以提升代码的可读性，可以限定值的范围，比如比赛结果，考试成绩，颜色种类，性别等等。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Sizes</span> &#123;<br>  <span class="hljs-title class_">Small</span>, <span class="hljs-comment">// Small = 0</span><br>  <span class="hljs-title class_">Medium</span>, <span class="hljs-comment">// Medium = 1</span><br>  <span class="hljs-title class_">Large</span>, <span class="hljs-comment">// Large = 2</span><br>&#125;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Sizes</span>.<span class="hljs-property">Small</span>); <span class="hljs-comment">// 0</span><br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Sizes</span> &#123;<br>  <span class="hljs-title class_">Small</span> = <span class="hljs-number">1</span>, <span class="hljs-comment">// Small = 1</span><br>  <span class="hljs-title class_">Medium</span>, <span class="hljs-comment">// Medium = 2</span><br>  <span class="hljs-title class_">Large</span>, <span class="hljs-comment">// Large = 3</span><br>&#125;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Sizes</span>.<span class="hljs-property">Small</span>); <span class="hljs-comment">// 1</span><br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 如果枚举值为非数值, 则每个属性都必须进行初始化</span><br><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Sizes</span> &#123;<br>  <span class="hljs-title class_">Small</span> = <span class="hljs-string">&quot;s&quot;</span>,<br>  <span class="hljs-title class_">Medium</span> = <span class="hljs-string">&quot;m&quot;</span>,<br>  <span class="hljs-title class_">Large</span> = <span class="hljs-string">&quot;l&quot;</span>,<br>&#125;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Sizes</span>.<span class="hljs-property">Small</span>); <span class="hljs-comment">// s</span><br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 枚举被编译为了 JavaScript 中的对象</span><br><span class="hljs-keyword">var</span> <span class="hljs-title class_">Sizes</span>;<br>(<span class="hljs-keyword">function</span> (<span class="hljs-params">Sizes</span>) &#123;<br>  <span class="hljs-title class_">Sizes</span>[<span class="hljs-string">&quot;Small&quot;</span>] = <span class="hljs-string">&quot;s&quot;</span>;<br>  <span class="hljs-title class_">Sizes</span>[<span class="hljs-string">&quot;Medium&quot;</span>] = <span class="hljs-string">&quot;m&quot;</span>;<br>  <span class="hljs-title class_">Sizes</span>[<span class="hljs-string">&quot;Large&quot;</span>] = <span class="hljs-string">&quot;l&quot;</span>;<br>&#125;)(<span class="hljs-title class_">Sizes</span> || (<span class="hljs-title class_">Sizes</span> = &#123;&#125;));<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 在声明枚举类型时, 如果使用 const 关键字, TypeScript 编译器将输出更加简洁的代码</span><br><span class="hljs-keyword">const</span> <span class="hljs-keyword">enum</span> <span class="hljs-title class_">Sizes</span> &#123;<br>  <span class="hljs-title class_">Small</span> = <span class="hljs-string">&quot;s&quot;</span>,<br>  <span class="hljs-title class_">Medium</span> = <span class="hljs-string">&quot;m&quot;</span>,<br>  <span class="hljs-title class_">Large</span> = <span class="hljs-string">&quot;l&quot;</span>,<br>&#125;<br><br><span class="hljs-keyword">let</span> selected = <span class="hljs-title class_">Sizes</span>.<span class="hljs-property">Large</span>;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(selected);<br></code></pre></td></tr></table></figure>

<h4 id="3-7-函数-Function"><a href="#3-7-函数-Function" class="headerlink" title="3.7 函数 Function"></a>3.7 函数 Function</h4><p>通过类型注释可以标注函数将要接收的参数的类型，函数将要返回的值的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">add</span>(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>): <span class="hljs-built_in">number</span> &#123;<br>  <span class="hljs-keyword">return</span> a + b;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">const</span> add = (<span class="hljs-attr">a</span>: <span class="hljs-built_in">number</span>, <span class="hljs-attr">b</span>: <span class="hljs-built_in">number</span>): <span class="hljs-function"><span class="hljs-params">number</span> =&gt;</span> &#123;<br>  <span class="hljs-keyword">return</span> a + b;<br>&#125;;<br><span class="hljs-comment">// TS2345: Argument of type &#x27;string&#x27; is not assignable to parameter of type &#x27;number&#x27;.</span><br><span class="hljs-title function_">sum</span>(<span class="hljs-number">10</span>, <span class="hljs-string">&quot;20&quot;</span>);<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// let logNumber: Function;</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">logNumber</span>: <span class="hljs-function">(<span class="hljs-params">n: <span class="hljs-built_in">number</span></span>) =&gt;</span> <span class="hljs-built_in">number</span>;<br>logNumber = <span class="hljs-function">(<span class="hljs-params">m</span>) =&gt;</span> &#123;<br>  <span class="hljs-keyword">return</span> m;<br>&#125;;<br></code></pre></td></tr></table></figure>

<p>如果函数没有返回值，可以使用 void 标注。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">log</span>(<span class="hljs-params"></span>): <span class="hljs-built_in">void</span> &#123;&#125;<br></code></pre></td></tr></table></figure>

<p>TypeScript 编译器会检查实参的类型及参数数量是否正确。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">sum</span>(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>): <span class="hljs-built_in">number</span> &#123;<br>  <span class="hljs-keyword">return</span> a + b;<br>&#125;<br><br><span class="hljs-comment">// TS2554: Expected 2 arguments, but got 3.</span><br><span class="hljs-title function_">sum</span>(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>);<br></code></pre></td></tr></table></figure>

<p>TypeScript 编译器会检测函数的返回值类型是否正确。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// TS2366: Function lacks ending return statement and return type does not include &#x27;undefined&#x27;.</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">sum</span>(<span class="hljs-params">a: <span class="hljs-built_in">number</span></span>): <span class="hljs-built_in">number</span> &#123;<br>  <span class="hljs-keyword">if</span> (a &gt; <span class="hljs-number">10</span>) <span class="hljs-keyword">return</span> a + <span class="hljs-number">20</span>;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>TypeScript 编译器会检测函数内部没有使用的变量。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">log</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-comment">// 未使用的 局部变量 x</span><br>  <span class="hljs-comment">// 移除未使用的 局部变量 &#x27;x&#x27;</span><br>  <span class="hljs-keyword">let</span> x;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>通过 ? 的方式设置可选参数, 它的类型是要么是它原本的类型要么是 undefined。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// c?: number | undefined</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">sum</span>(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span>, c?: <span class="hljs-built_in">number</span></span>): <span class="hljs-built_in">number</span> &#123;<br>  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> c !== <span class="hljs-string">&quot;undefined&quot;</span>) &#123;<br>    <span class="hljs-keyword">return</span> a + b + c;<br>  &#125;<br>  <span class="hljs-keyword">return</span> a + b;<br>&#125;<br><br><span class="hljs-title function_">sum</span>(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>);<br></code></pre></td></tr></table></figure>

<p>通过参数默认值的方式设置可选参数，它的类型就是原本的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// c?: number</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">sum</span>(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span>, c: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span></span>): <span class="hljs-built_in">number</span> &#123;<br>  <span class="hljs-keyword">return</span> a + b + c;<br>&#125;<br><br><span class="hljs-title function_">sum</span>(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>);<br></code></pre></td></tr></table></figure>

<p>在定义函数时，如果形参被定义为解构语法，则使用下面的方式为函数形参设置类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">const</span> <span class="hljs-title function_">logWeather</span> = (<span class="hljs-params">&#123; date, weather &#125;: &#123; date: <span class="hljs-built_in">Date</span>; weather: <span class="hljs-built_in">string</span> &#125;</span>) =&gt; &#123;<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(date, weather);<br>&#125;;<br><br><span class="hljs-keyword">const</span> today = &#123;<br>  <span class="hljs-attr">date</span>: <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(),<br>  <span class="hljs-attr">weather</span>: <span class="hljs-string">&quot;sunny&quot;</span>,<br>&#125;;<br><br><span class="hljs-title function_">logWeather</span>(today);<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">const</span> profile = &#123;<br>  <span class="hljs-comment">// 年龄</span><br>  <span class="hljs-attr">age</span>: <span class="hljs-number">20</span>,<br>  <span class="hljs-comment">// 坐标</span><br>  <span class="hljs-attr">coords</span>: &#123;<br>    <span class="hljs-attr">lat</span>: <span class="hljs-number">0</span>,<br>    <span class="hljs-attr">lng</span>: <span class="hljs-number">15</span>,<br>  &#125;,<br>&#125;;<br><br><span class="hljs-keyword">const</span> &#123; age &#125;: &#123; <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span> &#125; = profile;<br><span class="hljs-keyword">const</span> &#123; coords &#125;: &#123; <span class="hljs-attr">coords</span>: &#123; <span class="hljs-attr">lat</span>: <span class="hljs-built_in">number</span>; <span class="hljs-attr">lng</span>: <span class="hljs-built_in">number</span> &#125; &#125; = profile; <span class="hljs-comment">// &#123;lat: 0, lng: 15&#125;</span><br><span class="hljs-keyword">const</span> &#123;<br>  <span class="hljs-attr">coords</span>: &#123; lat, lng &#125;,<br>&#125;: &#123; <span class="hljs-attr">coords</span>: &#123; <span class="hljs-attr">lat</span>: <span class="hljs-built_in">number</span>; <span class="hljs-attr">lng</span>: <span class="hljs-built_in">number</span> &#125; &#125; = profile;<br><br><span class="hljs-comment">// const &#123; age &#125;: &#123; age: number &#125; = profile;</span><br><span class="hljs-comment">// const &#123;</span><br><span class="hljs-comment">//  coords: &#123; lat, lng &#125;,</span><br><span class="hljs-comment">// &#125;: &#123; coords: &#123; lat: number; lng: number &#125; &#125; = profile;</span><br></code></pre></td></tr></table></figure>

<h4 id="3-8-对象-Object"><a href="#3-8-对象-Object" class="headerlink" title="3.8 对象 Object"></a>3.8 对象 Object</h4><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 对象字面量</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">point</span>: &#123; <span class="hljs-attr">x</span>: <span class="hljs-built_in">number</span>; <span class="hljs-attr">y</span>: <span class="hljs-built_in">number</span> &#125; = &#123; <span class="hljs-attr">x</span>: <span class="hljs-number">100</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">200</span> &#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">employee</span>: &#123; <span class="hljs-keyword">readonly</span> <span class="hljs-attr">id</span>: <span class="hljs-built_in">number</span> &#125; = &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">1</span> &#125;;<br><br><span class="hljs-comment">// TS2540: Cannot assign to &#x27;id&#x27; because it is a read-only property.</span><br>employee.<span class="hljs-property">id</span> = <span class="hljs-number">2</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// TS2741: Property &#x27;name&#x27; is missing in type &#x27;&#123;&#125;&#x27; but required in type &#x27;&#123; name: string; &#125;&#x27;.</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">person</span>: &#123; <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span> &#125; = &#123;&#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> people = &#123;&#125;;<br><span class="hljs-comment">// TS2339: Property &#x27;name&#x27; does not exist on type &#x27;&#123;&#125;&#x27;.</span><br><span class="hljs-comment">// people.name = &quot;张三&quot;;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// age?: number | undefined</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">student</span>: &#123; age?: <span class="hljs-built_in">number</span> &#125; = &#123;&#125;;<br>student.<span class="hljs-property">age</span> = <span class="hljs-number">20</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 内置对象 类本身可以作为类实例的类型</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">date</span>: <span class="hljs-title class_">Date</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>();<br><br><span class="hljs-comment">// 自定义类</span><br><span class="hljs-comment">// 类可以作为类实例的类型</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Car</span> &#123;&#125;<br><span class="hljs-keyword">let</span> <span class="hljs-attr">car</span>: <span class="hljs-title class_">Car</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Car</span>();<br></code></pre></td></tr></table></figure>

<h4 id="3-9-类型推断"><a href="#3-9-类型推断" class="headerlink" title="3.9 类型推断"></a>3.9 类型推断</h4><p>TypeScript 编译器能根据一些简单的规则推断变量的类型。</p>
<p>在没有标注变量类型的情况下，编译器将变量初始值的类型作为该变量的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// let apples: number</span><br><span class="hljs-keyword">let</span> apples = <span class="hljs-number">5</span>;<br><span class="hljs-comment">// let speed: string</span><br><span class="hljs-keyword">let</span> speed = <span class="hljs-string">&quot;fast&quot;</span>;<br><span class="hljs-comment">// let hasName: boolean</span><br><span class="hljs-keyword">let</span> hasName = <span class="hljs-literal">true</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// let colors: string[]</span><br><span class="hljs-keyword">let</span> colors = [<span class="hljs-string">&quot;red&quot;</span>, <span class="hljs-string">&quot;green&quot;</span>, <span class="hljs-string">&quot;blue&quot;</span>];<br><span class="hljs-comment">// let numbers: number[]</span><br><span class="hljs-keyword">let</span> numbers = [<span class="hljs-number">100</span>, <span class="hljs-number">200</span>, <span class="hljs-number">300</span>];<br><span class="hljs-comment">// let bools: boolean[]</span><br><span class="hljs-keyword">let</span> bools = [<span class="hljs-literal">true</span>, <span class="hljs-literal">true</span>, <span class="hljs-literal">false</span>];<br><span class="hljs-comment">// let anything: never[]</span><br><span class="hljs-keyword">let</span> anything = [];<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">ary</span>: (<span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>)[] = [<span class="hljs-number">1</span>, <span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>, <span class="hljs-number">2</span>, <span class="hljs-string">&quot;c&quot;</span>, <span class="hljs-string">&quot;d&quot;</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// let point: &#123;x: number, y: number&#125;</span><br><span class="hljs-keyword">let</span> point = &#123; <span class="hljs-attr">x</span>: <span class="hljs-number">100</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">200</span> &#125;;<br></code></pre></td></tr></table></figure>

<p>TypeScript 编译器会试图推断函数返回值的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// const add: (a: number, b: number) =&gt; number</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">add</span> = (<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>) =&gt; &#123;<br>  <span class="hljs-keyword">return</span> a + b;<br>&#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// const add: (a: number, b: number) =&gt; void</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">add</span> = (<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>) =&gt; &#123;&#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// const add: (a: number, b: string) =&gt; string</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">add</span> = (<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">string</span></span>) =&gt; &#123;<br>  <span class="hljs-keyword">return</span> a + b;<br>&#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// const add: () =&gt; string</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">add</span> = (<span class="hljs-params"></span>) =&gt; &#123;<br>  <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;a&quot;</span>;<br>&#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// const find: (name: string) =&gt; string | boolean</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">find</span> = (<span class="hljs-params">name: <span class="hljs-built_in">string</span></span>) =&gt; &#123;<br>  <span class="hljs-keyword">if</span> (name) &#123;<br>    <span class="hljs-keyword">return</span> name;<br>  &#125; <span class="hljs-keyword">else</span> &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>  &#125;<br>&#125;;<br></code></pre></td></tr></table></figure>

<p>注意：使用函数返回值类型推断时，在编写函数内部代码时就失去了函数返回值类型检测功能，所以函数返回值的类型推荐明确指定。</p>
<p>在 TypeScript 编译器可以推断出变量类型的情况下，开发者不需要编写类型注释，也就是说只有在 TypeScript 不能正确推断变量类型的情况下开发者才需要编写类型注释，那么在哪些情况下 TypeScript 编译器不能正确推断出变量的类型呢？</p>
<p>① 如果变量声明后没有被立即初始化，TypeScript 编译器不能正确的推断出它的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 此时 TypeScript 编译器认为它是 Any 类型，即在该变量中可以存储任意类型的数据。</span><br><span class="hljs-comment">// 该变量失去了 TypeScript 中的类型检查功能</span><br><span class="hljs-comment">// let anything: any;</span><br><span class="hljs-keyword">let</span> anything;<br>anything = <span class="hljs-number">12</span>;<br>anything = <span class="hljs-string">&quot;hello&quot;</span>;<br>anything = <span class="hljs-literal">true</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 需求: 遍历 colors 数组, 从中查找绿色, 如果找到将 foundColor 变量的值设置为 true</span><br><span class="hljs-keyword">let</span> colors = [<span class="hljs-string">&quot;red&quot;</span>, <span class="hljs-string">&quot;green&quot;</span>, <span class="hljs-string">&quot;blue&quot;</span>];<br><span class="hljs-comment">// let foundColor: any</span><br><span class="hljs-comment">// 解决办法是要么设置初始值, 要么显式指定变量类型</span><br><span class="hljs-keyword">let</span> foundColor;<br><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; colors.<span class="hljs-property">length</span>; i++) &#123;<br>  <span class="hljs-keyword">if</span> (colors[i] === <span class="hljs-string">&quot;green&quot;</span>) &#123;<br>    <span class="hljs-comment">// 由于在声明 foundColor 时没有指定类型</span><br>    <span class="hljs-comment">// 所以此处除了布尔类型以外的其他类型的值也可以设置</span><br>    foundColor = <span class="hljs-literal">true</span>;<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>② 当调用的函数返回值为 Any 类型时，我们应该使用类型注释显式声明它的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// let json: string;</span><br><span class="hljs-keyword">let</span> json = <span class="hljs-string">&#x27;&#123;&quot;name&quot;: &quot;张三&quot;&#125;&#x27;</span>;<br><span class="hljs-comment">// let person: any =&gt; let person: &#123;name: string&#125;</span><br><span class="hljs-keyword">let</span> person = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(json);<br></code></pre></td></tr></table></figure>

<p>③ 当变量可能有多个类型的值时。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 需求: 在数组中查找大于 0 的数值, 如果找到将该值赋值给变量 target, 如果没有找到, 将 false 赋值给变量 target</span><br><span class="hljs-keyword">let</span> numbers = [-<span class="hljs-number">10</span>, -<span class="hljs-number">1</span>, <span class="hljs-number">20</span>];<br><span class="hljs-comment">// target =&gt; boolean | number</span><br><span class="hljs-keyword">let</span> target = <span class="hljs-literal">false</span>;<br><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; numbers.<span class="hljs-property">length</span>; i++) &#123;<br>  <span class="hljs-keyword">if</span> (numbers[i] &gt; <span class="hljs-number">0</span>) &#123;<br>    <span class="hljs-comment">// 不能将类型&quot;number&quot;分配给类型&quot;boolean&quot;</span><br>    target = numbers[i];<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">target</span>: <span class="hljs-built_in">boolean</span> | <span class="hljs-built_in">number</span> = <span class="hljs-literal">false</span>;<br></code></pre></td></tr></table></figure>

<p>④ 函数的参数必须标注类型，TypeScript 并不能推断函数参数的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// TS7006: Parameter &#x27;a&#x27; implicitly has an &#x27;any&#x27; type</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">sum</span>(<span class="hljs-params">a, b</span>) &#123;&#125;<br></code></pre></td></tr></table></figure>

<h3 id="4-TypeScript-高级类型"><a href="#4-TypeScript-高级类型" class="headerlink" title="4. TypeScript 高级类型"></a>4. TypeScript 高级类型</h3><h4 id="4-1-声明类型"><a href="#4-1-声明类型" class="headerlink" title="4.1 声明类型"></a>4.1 声明类型</h4><p>通过 type 关键字可以声明类型，声明的类型可以是基本数据类型也可以是复杂数据类型。</p>
<p>注意：通过 interface 只能声明复杂数据类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 也可以将此处的声明理解为 为 string 类型起了个别名</span><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">Name</span> = <span class="hljs-built_in">string</span>;<br><span class="hljs-keyword">let</span> <span class="hljs-attr">nameValue</span>: <span class="hljs-title class_">Name</span> = <span class="hljs-string">&quot;张三&quot;</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">Point</span> = &#123;<br>  <span class="hljs-attr">x</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-attr">y</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-attr">add</span>: <span class="hljs-function">(<span class="hljs-params">x: <span class="hljs-built_in">number</span>, y: <span class="hljs-built_in">number</span></span>) =&gt;</span> <span class="hljs-built_in">number</span>;<br>&#125;;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">point</span>: <span class="hljs-title class_">Point</span> = &#123; <span class="hljs-attr">x</span>: <span class="hljs-number">100</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">200</span>, <span class="hljs-attr">add</span>: <span class="hljs-function">(<span class="hljs-params">x: <span class="hljs-built_in">number</span>, y: <span class="hljs-built_in">number</span></span>) =&gt;</span> x + y &#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">Person</span> = &#123; <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>; <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span> &#125;;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">p1</span>: <span class="hljs-title class_">Person</span> = &#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">20</span> &#125;;<br><span class="hljs-keyword">let</span> <span class="hljs-attr">p2</span>: <span class="hljs-title class_">Person</span> = &#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;李四&quot;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">50</span> &#125;;<br><span class="hljs-keyword">let</span> <span class="hljs-attr">p3</span>: <span class="hljs-title class_">Person</span> = &#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;王五&quot;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">60</span> &#125;;<br><span class="hljs-keyword">let</span> <span class="hljs-attr">p4</span>: <span class="hljs-title class_">Person</span> = &#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;赵六&quot;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">35</span> &#125;;<br></code></pre></td></tr></table></figure>

<h4 id="4-2-联合类型"><a href="#4-2-联合类型" class="headerlink" title="4.2 联合类型"></a>4.2 联合类型</h4><p>联合类型是指将多个类型进行联合的使用，联合的结果就是新的类型。</p>
<p>为变量设置联合类型就意味着该变量可以是联合类型中的任意类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 联合类型: 为一个变量设置多个类型</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">a</span>: <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span> | <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">true</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// arg 参数既可以是字符串类型也可以是数值类型</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params">arg: <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span></span>) &#123;&#125;<br><span class="hljs-title function_">fn</span>(<span class="hljs-string">&quot;a&quot;</span>);<br><span class="hljs-title function_">fn</span>(<span class="hljs-number">10</span>);<br></code></pre></td></tr></table></figure>

<p>观察下列代码中存在的问题。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 披萨的尺寸</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">pizzaSize</span>: <span class="hljs-string">&quot;large&quot;</span> | <span class="hljs-string">&quot;medium&quot;</span> | <span class="hljs-string">&quot;small&quot;</span> = <span class="hljs-string">&quot;medium&quot;</span>;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">selectPizzaSize</span>(<span class="hljs-params">size: <span class="hljs-string">&quot;large&quot;</span> | <span class="hljs-string">&quot;medium&quot;</span> | <span class="hljs-string">&quot;small&quot;</span></span>) &#123;<br>  pizzaSize = size;<br>&#125;<br><br><span class="hljs-title function_">selectPizzaSize</span>(<span class="hljs-string">&quot;small&quot;</span>);<br></code></pre></td></tr></table></figure>

<p>以上代码同一个类型被声明了多次导致重复代码过多，可以使用 type 声明类型复用类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">Size</span> = <span class="hljs-string">&quot;large&quot;</span> | <span class="hljs-string">&quot;medium&quot;</span> | <span class="hljs-string">&quot;small&quot;</span>;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">pizzaSize</span>: <span class="hljs-title class_">Size</span> = <span class="hljs-string">&quot;medium&quot;</span>;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">selectPizzaSize</span>(<span class="hljs-params">size: Size</span>) &#123;<br>  pizzaSize = size;<br>&#125;<br><br><span class="hljs-title function_">selectPizzaSize</span>(<span class="hljs-string">&quot;large&quot;</span>);<br></code></pre></td></tr></table></figure>

<h4 id="4-3-交叉类型"><a href="#4-3-交叉类型" class="headerlink" title="4.3 交叉类型"></a>4.3 交叉类型</h4><p>交叉类型是指将多个类型叠加合并组成新的类型，新类型中包含了被合并类型的所有属性。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">Draggable</span> = &#123;<br>  <span class="hljs-attr">drag</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;<br>&#125;;<br><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">Resizable</span> = &#123;<br>  <span class="hljs-attr">resize</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;<br>&#125;;<br><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">UIWidget</span> = <span class="hljs-title class_">Draggable</span> &amp; <span class="hljs-title class_">Resizable</span>;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">textBox</span>: <span class="hljs-title class_">UIWidget</span> = &#123;<br>  <span class="hljs-attr">drag</span>: <span class="hljs-function">() =&gt;</span> &#123;&#125;,<br>  <span class="hljs-attr">resize</span>: <span class="hljs-function">() =&gt;</span> &#123;&#125;,<br>&#125;;<br></code></pre></td></tr></table></figure>

<h4 id="4-4-字面量类型"><a href="#4-4-字面量类型" class="headerlink" title="4.4 字面量类型"></a>4.4 字面量类型</h4><p>字面量类型是指将字面量值的类型作为变量的类型，将字面量值作为变量的取值范围。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">Quantity</span> = <span class="hljs-number">10</span>;<br><span class="hljs-keyword">let</span> <span class="hljs-attr">quantity</span>: <span class="hljs-title class_">Quantity</span> = <span class="hljs-number">10</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">Quantity</span> = <span class="hljs-number">50</span> | <span class="hljs-number">100</span>;<br><br><span class="hljs-comment">// TS2322: Type &#x27;54&#x27; is not assignable to type &#x27;Quantity&#x27;.</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">quantity</span>: <span class="hljs-title class_">Quantity</span> = <span class="hljs-number">54</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">Metric</span> = <span class="hljs-string">&quot;cm&quot;</span> | <span class="hljs-string">&quot;inch&quot;</span>;<br><br><span class="hljs-comment">// TS2322: Type &#x27;&quot;abc&quot;&#x27; is not assignable to type &#x27;Metric&#x27;.</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">metric</span>: <span class="hljs-title class_">Metric</span> = <span class="hljs-string">&quot;abc&quot;</span>;<br></code></pre></td></tr></table></figure>

<h4 id="4-5-可空类型"><a href="#4-5-可空类型" class="headerlink" title="4.5 可空类型"></a>4.5 可空类型</h4><p>在 TypeScript 中，undefined 和 null 这两个值本身也可以作为类型使用。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// undefined</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">nothing</span>: <span class="hljs-literal">undefined</span> = <span class="hljs-literal">undefined</span>;<br><span class="hljs-comment">// null</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">nothingMuch</span>: <span class="hljs-literal">null</span> = <span class="hljs-literal">null</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">greet</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span> | <span class="hljs-literal">undefined</span></span>) &#123;<br>  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> name === <span class="hljs-string">&quot;string&quot;</span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(name.<span class="hljs-title function_">toLowerCase</span>());<br>  &#125; <span class="hljs-keyword">else</span> &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;something went wrong&quot;</span>);<br>  &#125;<br>&#125;<br><br><span class="hljs-title function_">greet</span>(<span class="hljs-literal">undefined</span>);<br></code></pre></td></tr></table></figure>

<h4 id="4-6-可选链操作符"><a href="#4-6-可选链操作符" class="headerlink" title="4.6 可选链操作符"></a>4.6 可选链操作符</h4><blockquote>
<p>目标：掌握可选链操作符的使用方式</p>
</blockquote>
<hr>
<ul>
<li><input disabled type="checkbox"> 分析一段 JavaScript 代码，为讲解可选链操作符做铺垫</li>
<li><input disabled type="checkbox"> 可选链操作符和对象一起使用</li>
<li><input disabled type="checkbox"> 可选链操作符和数组一起使用</li>
<li><input disabled type="checkbox"> 可选链操作符和函数一起使用</li>
</ul>
<hr>
<p>① 先来看一段 JavaScript 中的代码，分析代码中的潜在问题。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// person 对象中的 name 属性是可选的, 即 person 对象中可能有 name 属性也可能没有 name 属性</span><br><span class="hljs-comment">// 如果 name 属性存在, 它是字符串类型</span><br><span class="hljs-keyword">const</span> person = &#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;John&quot;</span> &#125;;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(person.<span class="hljs-property">name</span>.<span class="hljs-title function_">toUpperCase</span>()); <span class="hljs-comment">// JOHN</span><br></code></pre></td></tr></table></figure>

<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> person = &#123;&#125;;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(person.<span class="hljs-property">name</span>.<span class="hljs-title function_">toUpperCase</span>());<br><span class="hljs-comment">// Uncaught TypeError: Cannot read properties of undefined (reading &#x27;toUpperCase&#x27;)</span><br></code></pre></td></tr></table></figure>

<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> person = &#123;&#125;;<br><span class="hljs-keyword">if</span> (person.<span class="hljs-property">name</span>) <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(person.<span class="hljs-property">name</span>.<span class="hljs-title function_">toUpperCase</span>());<br></code></pre></td></tr></table></figure>

<p>可选链操作符( <code>?.</code> )允许开发者安全的链式访问一个对象上可能为 <code>null</code> 或 <code>undefined</code> 的属性。</p>
<p>② 可选链操作符和对象一起使用</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> &#123;<br>  name?: <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">const</span> <span class="hljs-attr">person</span>: <span class="hljs-title class_">Person</span> = &#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span> &#125;;<br>person.<span class="hljs-property">name</span>?.<span class="hljs-title function_">toLocaleUpperCase</span>();<br></code></pre></td></tr></table></figure>

<p>③ 可选链操作符和数组一起使用</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> &#123;<br>  <span class="hljs-attr">skills</span>: <span class="hljs-built_in">string</span>[] | <span class="hljs-literal">null</span>;<br>&#125;<br><br><span class="hljs-keyword">const</span> <span class="hljs-attr">person</span>: <span class="hljs-title class_">Person</span> = &#123;<br>  <span class="hljs-attr">skills</span>: [<span class="hljs-string">&quot;编程&quot;</span>, <span class="hljs-string">&quot;开锁&quot;</span>, <span class="hljs-string">&quot;飞檐走壁&quot;</span>],<br>&#125;;<br><br>person.<span class="hljs-property">skills</span>?.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(item));<br></code></pre></td></tr></table></figure>

<p>③ 可选链操作符和函数一起使用</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> &#123;<br>  sayHello?: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;<br>&#125;<br><br><span class="hljs-keyword">const</span> <span class="hljs-attr">person</span>: <span class="hljs-title class_">Person</span> = &#123;<br>  <span class="hljs-attr">sayHello</span>: <span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-title function_">alert</span>(<span class="hljs-string">&quot;Hello&quot;</span>);<br>  &#125;,<br>&#125;;<br><br>person.<span class="hljs-property">sayHello</span>?.();<br></code></pre></td></tr></table></figure>

<h4 id="4-7-空值合并运算符"><a href="#4-7-空值合并运算符" class="headerlink" title="4.7 空值合并运算符"></a>4.7 空值合并运算符</h4><p>空值合并运算符 (<code>??</code>) 是一个逻辑运算符，当左侧的运算数为 null 或者 undefined 时，返回其右侧运算数，否则返回左侧运算数。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">speed</span>: <span class="hljs-built_in">number</span> | <span class="hljs-literal">null</span> = <span class="hljs-literal">null</span>;<br><br><span class="hljs-keyword">let</span> ride = &#123;<br>  <span class="hljs-comment">// speed: speed !== null ? speed : 30,</span><br>  <span class="hljs-attr">speed</span>: speed ?? <span class="hljs-number">30</span>,<br>&#125;;<br></code></pre></td></tr></table></figure>

<h4 id="4-8-类型断言"><a href="#4-8-类型断言" class="headerlink" title="4.8 类型断言"></a>4.8 类型断言</h4><p>通过类型断言可以覆盖 TypeScript 编译器的推断，当开发者比 TypeScript 更加清楚它的类型时使用。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// const phone: HTMLElement | null</span><br><span class="hljs-keyword">const</span> phone = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&quot;phone&quot;</span>);<br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>((&lt;<span class="hljs-title class_">HTMLInputElement</span>&gt;phone).<span class="hljs-property">value</span>);<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>((phone <span class="hljs-keyword">as</span> <span class="hljs-title class_">HTMLInputElement</span>).<span class="hljs-property">value</span>);<br></code></pre></td></tr></table></figure>

<h4 id="4-9-unknown-类型"><a href="#4-9-unknown-类型" class="headerlink" title="4.9 unknown 类型"></a>4.9 unknown 类型</h4><p>unknow 是严格的 any 类型，在对 unknown 类型的变量执行操作之前必须先确定它的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">anything</span>: <span class="hljs-built_in">unknown</span> = <span class="hljs-string">&quot;Hello TypeScript&quot;</span>;<br>anything = <span class="hljs-literal">true</span>; <span class="hljs-comment">// ✅</span><br>anything = <span class="hljs-number">3.14</span>; <span class="hljs-comment">// ✅</span><br>anything = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;&#125;; <span class="hljs-comment">// ✅</span><br><br><span class="hljs-comment">// TS2571: Object is of type &#x27;unknown&#x27;. ❎</span><br><span class="hljs-comment">// console.log(anything.length);</span><br><br><span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> anything === <span class="hljs-string">&quot;number&quot;</span>) &#123;<br>  anything.<span class="hljs-title function_">toFixed</span>();<br>&#125; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> anything === <span class="hljs-string">&quot;string&quot;</span>) &#123;<br>  anything.<span class="hljs-title function_">toUpperCase</span>();<br>&#125; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> anything === <span class="hljs-string">&quot;function&quot;</span>) &#123;<br>  <span class="hljs-title function_">anything</span>();<br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="4-10-never-类型"><a href="#4-10-never-类型" class="headerlink" title="4.10 never 类型"></a>4.10 never 类型</h4><p>never 表示永远不会发生的类型，即永远不能有值。比如用于抛出错误的函数，用于执行无限循环的函数，它们的返回值就是 never，再比如 never[]，表示数组中不会有值。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">const</span> throwError = (<span class="hljs-attr">message</span>: <span class="hljs-built_in">string</span>): <span class="hljs-function"><span class="hljs-params">never</span> =&gt;</span> &#123;<br>  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(message);<br>&#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// const throwError: (message: string) =&gt; void</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">throwError</span> = (<span class="hljs-params">message: <span class="hljs-built_in">string</span></span>) =&gt; &#123;<br>  <span class="hljs-keyword">if</span> (!message) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">&quot;error&quot;</span>);<br>&#125;;<br></code></pre></td></tr></table></figure>

<p>注意：如果一个函数永远都不会有返回值，说明函数调用位置后面的代码永远都不会被执行。</p>
<h3 id="5-面向对象编程"><a href="#5-面向对象编程" class="headerlink" title="5. 面向对象编程"></a>5. 面向对象编程</h3><h4 id="5-1-概述"><a href="#5-1-概述" class="headerlink" title="5.1 概述"></a>5.1 概述</h4><p>面向对象和面向过程都属于编写程序的指导思想，指导开发者按照什么样的套路编写代码。</p>
<p>面向过程是侧重于过程的编程，即按照功能代码的执行顺序编写代码。在编写程序时要明确知道每一步要做什么，比如将大象装冰箱一共分为三步，那么按照步骤编写代码即可。</p>
<p>面向对象是侧重于对象的编程，开发者站在上帝视角，要想什么就创建什么对象，然后赋予对象做事情的能力，要做的事情让对象自己完成。比如将大象装冰箱，我们要创建大象对象，创建冰箱对象，赐予大象进冰箱的能力，然后让大象自己进冰箱。</p>
<p>面向过程的优点是简单，思考简单，编写简单。</p>
<p>面向过程的缺点是代码量越大维护成本越高。当程序出问题后，需要从头到尾将步骤过一遍，在此过程中找问题，修复问题，如果代码中步骤非常多的话，是非常耗时间和精力的。</p>
<p>面向对象的优点的是扩展性强维护成本低，当程序出问题后定位对象即可，哪个对象出问题就找哪个对象修复哪个对象就可以了。</p>
<p>面向对象的缺点是新人上手难度高。</p>
<h4 id="5-2-类与对象"><a href="#5-2-类与对象" class="headerlink" title="5.2 类与对象"></a>5.2 类与对象</h4><p>在面向对象中通过对象来表示具体的事物，对象才可以干具体的事情，那么我们如何创建对象呢？比如创建一个表示车的对象。</p>
<p>现实世界中第一步是画车辆图纸，在图纸中定义车的特征和车的能力，比如车是什么颜色，有多少座位，车可以驾驶。第二步是根据图纸造真实车辆。</p>
<p>面向对象中使用类表示图纸，定义类就是画图纸，类中包含两部分，属性和方法，属性就是特征，方法就是能力。通过类可以创造对象。对象能干什么完全取决于你的类是如何定义的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Vehicle</span> &#123;<br>  <span class="hljs-comment">// 特性: 颜色</span><br>  color = <span class="hljs-string">&quot;白色&quot;</span>;<br>  <span class="hljs-comment">// 特性: 最高速度</span><br>  maxSpeed = <span class="hljs-number">220</span>;<br>  <span class="hljs-comment">// 能力: 驾驶</span><br>  <span class="hljs-title function_">drive</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;run&quot;</span>);<br>  &#125;<br>  <span class="hljs-comment">// 能力: 鸣笛</span><br>  <span class="hljs-title function_">honk</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;didi&quot;</span>);<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">const</span> vehicle = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vehicle</span>();<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(vehicle);<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(vehicle.<span class="hljs-property">color</span>);<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(vehicle.<span class="hljs-property">maxSpeed</span>);<br>vehicle.<span class="hljs-title function_">drive</span>();<br>vehicle.<span class="hljs-title function_">honk</span>();<br></code></pre></td></tr></table></figure>

<p>通过同一个类可以创建多个相同的实物对象，所以属性就是这一类事物拥有的共同特性，方法就是这一类事物拥有的共同的能力。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">const</span> v1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vehicle</span>();<br><span class="hljs-keyword">const</span> v2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vehicle</span>();<br><span class="hljs-keyword">const</span> v3 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vehicle</span>();<br></code></pre></td></tr></table></figure>

<p>通过类创建出来的对象也被称之为实例对象。</p>
<h4 id="5-3-构造函数"><a href="#5-3-构造函数" class="headerlink" title="5.3 构造函数"></a>5.3 构造函数</h4><p>构造函数用来为对象属性赋初始值或者执行初始化操作，构造函数的名字是固定的，即 constructor。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Vehicle</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>) &#123;&#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>在使用 new 关键字创建对象时可以传递参数、该参数在类的内部通过构造函数接收，参数值一般就是对象中某个属性的初始值。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Vehicle</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params">color: <span class="hljs-built_in">string</span>, maxSpeed: <span class="hljs-built_in">number</span></span>) &#123;&#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> vehicle = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vehicle</span>(<span class="hljs-string">&quot;红色&quot;</span>, <span class="hljs-number">240</span>);<br></code></pre></td></tr></table></figure>

<p>在构造函数中 this 关键字指向的是通过类创建出来的对象，所以通过 this 可以找到对象的属性，然后就可以为属性赋值了。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Vehicle</span> &#123;<br>  <span class="hljs-attr">color</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">maxSpeed</span>: <span class="hljs-built_in">number</span>;<br><br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params">color: <span class="hljs-built_in">string</span>, maxSpeed: <span class="hljs-built_in">number</span></span>) &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">color</span> = color;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">maxSpeed</span> = maxSpeed;<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> vehicle = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vehicle</span>(<span class="hljs-string">&quot;红色&quot;</span>, <span class="hljs-number">240</span>);<br></code></pre></td></tr></table></figure>

<p>类的构造函数是被自动调用的，在使用 new 关键字创建对象时被自动调用。</p>
<h4 id="5-4-只读属性"><a href="#5-4-只读属性" class="headerlink" title="5.4 只读属性"></a>5.4 只读属性</h4><p>只读属性是指属性一旦被赋值，该值就不能被修改。</p>
<p>在类中通过 readonly 修饰符将类属性设置为只读属性。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Vehicle</span> &#123;<br>  <span class="hljs-keyword">readonly</span> <span class="hljs-attr">maxSpeed</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params">maxSpeed: <span class="hljs-built_in">number</span></span>) &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">maxSpeed</span> = maxSpeed;<br>  &#125;<br><br>  <span class="hljs-title function_">drive</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">//  TS2540: Cannot assign to &#x27;maxSpeed&#x27; because it is a read-only property.</span><br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">maxSpeed</span> = <span class="hljs-number">900</span>;<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> vehicle = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vehicle</span>(<span class="hljs-number">240</span>);<br><span class="hljs-comment">// TS2540: Cannot assign to &#x27;maxSpeed&#x27; because it is a read-only property.</span><br>vehicle.<span class="hljs-property">maxSpeed</span> = <span class="hljs-number">300</span>;<br></code></pre></td></tr></table></figure>

<h4 id="5-5-继承"><a href="#5-5-继承" class="headerlink" title="5.5 继承"></a>5.5 继承</h4><p>在面向对象编程中，很多对象都会具有相同的特征和能力，比如猫对象和狗对象，它们都具有五官特征都具备吃饭和奔跑的能力，如果我们分别在猫类和狗类中定义五官特征和奔跑能力的话，那么程序中将出现大量的重复性代码。</p>
<p>要解决上述问题，我们可以对类别进行更高级别的抽象，比如我们可以再定义一个动物类，将动物具备的通用特性定义在动物类中，比如五官特征和奔跑吃饭的能力。那么猫类和狗类如何拥有这些特征和能力呢？</p>
<p>答案就是继承，通过继承可以让具体的猫类和狗类拥有这些特征和能力，这样程序中就不会出现重复性代码了，然后我们还可以在猫类和狗类中继续定义属于猫和狗的独有特征和能力。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Animal</span> &#123;&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Animal</span> &#123;&#125;<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Cat</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Animal</span> &#123;&#125;<br></code></pre></td></tr></table></figure>

<p>在以上代码中，Animal 被称之为父类，Dog 和 Cat 被称之为子类。</p>
<p>在程序中分别创建汽车分类，轿车分类、面包车分类，在汽车分类下描述所有汽车的通用特征，在细化分类下只描述该分类独有的特征。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 汽车分类</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Vehicle</span> &#123;<br>  <span class="hljs-title function_">drive</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;run&quot;</span>);<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Car</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Vehicle</span> &#123;<br>  brand = <span class="hljs-string">&quot;BMW&quot;</span>;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Van</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Vehicle</span> &#123;<br>  brand = <span class="hljs-string">&quot;五菱宏光&quot;</span>;<br>&#125;<br><br><span class="hljs-keyword">let</span> car = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Car</span>();<br>car.<span class="hljs-title function_">drive</span>();<br>car.<span class="hljs-property">brand</span>;<br><br><span class="hljs-keyword">let</span> van = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Van</span>();<br>van.<span class="hljs-title function_">drive</span>();<br>van.<span class="hljs-property">brand</span>;<br></code></pre></td></tr></table></figure>

<p>在子类继承父类后，如果父类需要在初始化的时候传递参数，该参数由子类接收，在子类的构造函数中通过 super 调用父类将参数传递给父类。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> name: <span class="hljs-built_in">string</span></span>) &#123;&#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Person</span> &#123;<br>  <span class="hljs-comment">// 注意: 在子类继承父类后, 如果要在子类中使用构造函数, 即使父类不需要传递参数</span><br>  <span class="hljs-comment">// 在构造函数中的第一件事情也是必须先调用 super 方法</span><br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> studentId: <span class="hljs-built_in">number</span>, name: <span class="hljs-built_in">string</span></span>) &#123;<br>    <span class="hljs-variable language_">super</span>(name);<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> p1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>(<span class="hljs-number">1</span>, <span class="hljs-string">&quot;张三&quot;</span>);<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p1.<span class="hljs-property">studentId</span>);<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p1.<span class="hljs-property">name</span>);<br></code></pre></td></tr></table></figure>

<p>子类在继承父类后，还可以通过重写父类方法对功能进行扩展。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> &#123;<br>  <span class="hljs-title function_">walk</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;person walk&quot;</span>);<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Person</span> &#123;<br>  <span class="hljs-comment">// override 表示该方法是覆盖的父类方法, 仅作为标识提升代码的可阅读性, 不会对代码的实际执行产生任何副作用</span><br>  <span class="hljs-keyword">override</span> <span class="hljs-title function_">walk</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;student walk&quot;</span>);<br>    <span class="hljs-comment">// 通过 super 调用父类 walk 方法</span><br>    <span class="hljs-variable language_">super</span>.<span class="hljs-title function_">walk</span>();<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> p1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>();<br>p1.<span class="hljs-title function_">walk</span>();<br></code></pre></td></tr></table></figure>

<h4 id="5-6-访问权限修饰符"><a href="#5-6-访问权限修饰符" class="headerlink" title="5.6 访问权限修饰符"></a>5.6 访问权限修饰符</h4><p>通过访问权限修饰符可以指定类中的属性、方法能够在哪些范围内被访问。</p>
<table>
<thead>
<tr>
<th>修饰符</th>
<th>作用</th>
</tr>
</thead>
<tbody><tr>
<td>public</td>
<td>被 public 关键字修饰的类属性和类方法可以在任何地方使用 (当前类、子类、实例对象)</td>
</tr>
<tr>
<td>private</td>
<td>被 private 关键字修饰的类属性和类方法只能在当前类中使用</td>
</tr>
<tr>
<td>protected</td>
<td>被 protected 关键字修饰的类属性和类方法可以在当前类和子类中使用</td>
</tr>
</tbody></table>
<p><strong>① public 公开的</strong></p>
<p>类属性和类方法在不加任何权限修饰符的情况下，它就是可以在任何地方被访问的，也就是说 public 是默认值，是可以被省略的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Vehicle</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 1. 在本类中的其他方法中使用</span><br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">drive</span>();<br>  &#125;<br>  <span class="hljs-keyword">public</span> <span class="hljs-title function_">drive</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;run&quot;</span>);<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Car</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Vehicle</span> &#123;<br>  <span class="hljs-title function_">drive</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 2. 在子类中使用</span><br>    <span class="hljs-variable language_">super</span>.<span class="hljs-title function_">drive</span>();<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> car = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Car</span>();<br><span class="hljs-comment">// 3. 在实例对象中使用</span><br>car.<span class="hljs-title function_">drive</span>();<br></code></pre></td></tr></table></figure>

<p><strong>② private 私有的</strong></p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Vehicle</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 在本类中的其他方法中使用</span><br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">drive</span>();<br>  &#125;<br>  <span class="hljs-keyword">private</span> <span class="hljs-title function_">drive</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;run&quot;</span>);<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Car</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Vehicle</span> &#123;<br>  <span class="hljs-title function_">drive</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 属性&quot;drive&quot;为私有属性，只能在类&quot;Vehicle&quot;中访问</span><br>    <span class="hljs-variable language_">super</span>.<span class="hljs-title function_">drive</span>();<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> vehicle = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vehicle</span>();<br><span class="hljs-comment">// 属性&quot;drive&quot;为私有属性，只能在类&quot;Vehicle&quot;中访问</span><br>vehicle.<span class="hljs-title function_">drive</span>();<br></code></pre></td></tr></table></figure>

<p><strong>③ protected 受保护的</strong></p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Vehicle</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 1. 在本类中的其他方法中使用</span><br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">drive</span>();<br>  &#125;<br>  <span class="hljs-keyword">protected</span> <span class="hljs-title function_">drive</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;run&quot;</span>);<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Car</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Vehicle</span> &#123;<br>  <span class="hljs-title function_">drive</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 2. 在子类中使用</span><br>    <span class="hljs-variable language_">super</span>.<span class="hljs-title function_">drive</span>();<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> vehicle = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vehicle</span>();<br><span class="hljs-comment">// 属性&quot;drive&quot;受保护, 只能在类&quot;Vehicle&quot;及其子类中访问</span><br>vehicle.<span class="hljs-title function_">drive</span>();<br></code></pre></td></tr></table></figure>

<h4 id="5-7-Getter-与-Setter"><a href="#5-7-Getter-与-Setter" class="headerlink" title="5.7 Getter 与 Setter"></a>5.7 Getter 与 Setter</h4><p>Getter 和 Setter 是对属性访问(获取和设置)的封装，获取属性值时走 Getter，修改属性值时走 Setter。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Employee</span> &#123;<br>  <span class="hljs-keyword">private</span> <span class="hljs-attr">_salary</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params">salary: <span class="hljs-built_in">number</span></span>) &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">_salary</span> = salary;<br>  &#125;<br><br>  <span class="hljs-keyword">get</span> <span class="hljs-title function_">salary</span>() &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_salary</span>;<br>  &#125;<br><br>  <span class="hljs-keyword">set</span> <span class="hljs-title function_">salary</span>(<span class="hljs-params">salary: <span class="hljs-built_in">number</span></span>) &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">_salary</span> = salary;<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> employee = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-number">4000</span>);<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(employee.<span class="hljs-property">salary</span>);<br>employee.<span class="hljs-property">salary</span> = <span class="hljs-number">6000</span>;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(employee.<span class="hljs-property">salary</span>);<br></code></pre></td></tr></table></figure>

<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 通过选项的方式指定 target</span><br>tsc -t es2016 index.ts<br><span class="hljs-comment"># 通过配置文件的方式指定 target</span><br>tsc --init<br><span class="hljs-comment"># 若要走配置文件 直接执行 tsc 命令</span><br>tsc<br></code></pre></td></tr></table></figure>

<h4 id="5-8-参数属性"><a href="#5-8-参数属性" class="headerlink" title="5.8 参数属性"></a>5.8 参数属性</h4><p>TypeScript 提供了特殊的语法将构造函数参数转换为具有相同名称的类属性。</p>
<p>通过在构造函数参数的前面加上权限修饰符 public、private、protected 或 readonly 创建。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Params</span> &#123;<br>  <span class="hljs-attr">x</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-attr">y</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-attr">z</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params">x: <span class="hljs-built_in">number</span>, y: <span class="hljs-built_in">number</span>, z: <span class="hljs-built_in">number</span></span>) &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">x</span> = x;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">y</span> = y;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">z</span> = z;<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Params</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> x: <span class="hljs-built_in">number</span>, <span class="hljs-keyword">public</span> y: <span class="hljs-built_in">number</span>, <span class="hljs-keyword">public</span> z: <span class="hljs-built_in">number</span></span>) &#123;&#125;<br><br>  <span class="hljs-title function_">log</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">x</span>);<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">y</span>);<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">z</span>);<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> p = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Params</span>(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>);<br>p.<span class="hljs-title function_">log</span>();<br></code></pre></td></tr></table></figure>

<h4 id="5-9-索引签名"><a href="#5-9-索引签名" class="headerlink" title="5.9 索引签名"></a>5.9 索引签名</h4><p>在 JavaScript 中，为对象动态添加属性是被允许的，但是在 TypeScript 中是不行的，因为在 TypeScript 中对象要有严格的类型限制。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> person = &#123;&#125;;<br><span class="hljs-comment">// TS2339: Property &#x27;name&#x27; does not exist on type &#x27;&#123;&#125;&#x27;.</span><br>person.<span class="hljs-property">name</span> = <span class="hljs-string">&quot;张三&quot;</span>;<br></code></pre></td></tr></table></figure>

<p>在 TypeScript 中动态为对象添加属性，需要使用索引签名，通过索引签名可以在不确定属性名称的情况下限制对象属性的类型以及对象值的类型。</p>
<p>在不确定属性名称的情况下限制属性的类型意味着我们可以动态的为对象添加任意属性，但属性类型要符合要求。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">SeatAssignment</span> &#123;<br>  <span class="hljs-attr">A1</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">A2</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-comment">// ....</span><br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">SeatAssignment</span> &#123;<br>  <span class="hljs-comment">// seatNumber 只是用来占位的, 实际属性的名称开发者可以自定义，而且 seatNumber 也可以换成其他名称</span><br>  [<span class="hljs-attr">seatNumber</span>: <span class="hljs-built_in">string</span>]: <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">let</span> seats = <span class="hljs-keyword">new</span> <span class="hljs-title class_">SeatAssignment</span>();<br><br>seats.<span class="hljs-property">A1</span> = <span class="hljs-string">&quot;张三&quot;</span>;<br>seats.<span class="hljs-property">A2</span> = <span class="hljs-string">&quot;李四&quot;</span>;<br><br><span class="hljs-comment">// ❎ TS2538: Type &#x27;true&#x27; cannot be used as an index type.</span><br>seats[<span class="hljs-literal">true</span>] = <span class="hljs-string">&quot;Hello&quot;</span>;<br><br><span class="hljs-comment">// ❎ TS2322: Type &#x27;number&#x27; is not assignable to type &#x27;string&#x27;.</span><br>seats.<span class="hljs-property">A3</span> = <span class="hljs-number">12</span>;<br></code></pre></td></tr></table></figure>

<h4 id="5-10-静态成员"><a href="#5-10-静态成员" class="headerlink" title="5.10 静态成员"></a>5.10 静态成员</h4><p>在类中被 static 关键字修饰的类属性和类方法被叫做静态成员，静态成员属于类，所以访问静态成员的方式是类名点上静态成员名称。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Rich</span> &#123;<br>  <span class="hljs-keyword">static</span> <span class="hljs-attr">count</span>: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span>;<br>&#125;<br><span class="hljs-comment">// 通过 类名 + 静态成员名称 访问静态成员</span><br><span class="hljs-title class_">Rich</span>.<span class="hljs-property">count</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 以下写法错误</span><br><span class="hljs-comment">// 静态成员不属于类的实例对象, 所以不能通过类的实例对象访问静态成员</span><br><span class="hljs-keyword">const</span> r = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Rich</span>();<br><span class="hljs-comment">// TS2576: Property &#x27;count&#x27; does not exist on type &#x27;Rich&#x27;.</span><br><span class="hljs-comment">// Did you mean to access the static member &#x27;Rich.count&#x27; instead?</span><br>r.<span class="hljs-property">count</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Rich</span> &#123;<br>  <span class="hljs-keyword">static</span> <span class="hljs-attr">count</span>: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span>;<br>  <span class="hljs-title function_">getCount</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-title class_">Rich</span>.<span class="hljs-property">count</span>;<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>对于该类的任何一个对象而言，静态属性就是公共的存储单元，该类的任何对象访问它时，取到的都是相同的值，该类的任何对象修改它时，也都是在对同一个内存单元做操作，所以静态属性主要用在各个对象都要共享的数据。</p>
<p>目标: 获取类的实例对象的数量。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Rich</span> &#123;<br>  <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-attr">_count</span>: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span>;<br><br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-title class_">Rich</span>.<span class="hljs-property">_count</span>++;<br>  &#125;<br><br>  <span class="hljs-title function_">getCount</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-title class_">Rich</span>.<span class="hljs-property">_count</span>;<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> r1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Rich</span>();<br><span class="hljs-keyword">const</span> r2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Rich</span>();<br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(r1.<span class="hljs-title function_">getCount</span>());<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(r2.<span class="hljs-title function_">getCount</span>());<br></code></pre></td></tr></table></figure>

<p>因为静态成员始终存在于内存，而非静态成员需要实例化才可以分配到内存，所以静态成员不能访问非静态成员，非静态成员可以访问类中的静态成员。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Rich</span> &#123;<br>  <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-attr">_count</span>: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span>;<br>  <span class="hljs-comment">// 静态成员中不能访问非静态成员</span><br>  <span class="hljs-comment">// 静态方法中的 this 指向了类, 而不是类实例</span><br>  <span class="hljs-keyword">static</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// TS2339: Property &#x27;getCount&#x27; does not exist on type &#x27;typeof Rich&#x27;.</span><br>    <span class="hljs-comment">// this.getCount();</span><br>  &#125;<br>  <span class="hljs-comment">// 非静态成员中可以访问静态成员</span><br>  <span class="hljs-title function_">getCount</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-title class_">Rich</span>.<span class="hljs-property">_count</span>;<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="5-11-抽象类"><a href="#5-11-抽象类" class="headerlink" title="5.11 抽象类"></a>5.11 抽象类</h4><p>抽象类因继承而存在，通过抽象类可以约束子类必须实现哪些成员，如果抽象类不被继承，它将毫无意义。</p>
<p>在抽象类中可以只定义成员，具体的成员实现由子类完成且必须完成，所以抽象类不能被直接实例化。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Shape</span> &#123;<br>  <span class="hljs-keyword">abstract</span> <span class="hljs-attr">color</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-keyword">abstract</span> <span class="hljs-title function_">render</span>(): <span class="hljs-built_in">void</span>;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Circle</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Shape</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> color: <span class="hljs-built_in">string</span></span>) &#123;<br>    <span class="hljs-variable language_">super</span>();<br>  &#125;<br>  <span class="hljs-keyword">override</span> <span class="hljs-title function_">render</span>(): <span class="hljs-built_in">void</span> &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;render&quot;</span>);<br>  &#125;<br>&#125;<br><br><span class="hljs-comment">// TS2511: Cannot create an instance of an abstract class.</span><br><span class="hljs-comment">// new Shape();</span><br><br><span class="hljs-keyword">const</span> circle = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Circle</span>(<span class="hljs-string">&quot;red&quot;</span>);<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(circle.<span class="hljs-property">color</span>);<br>circle.<span class="hljs-title function_">render</span>();<br></code></pre></td></tr></table></figure>

<h4 id="5-12-接口"><a href="#5-12-接口" class="headerlink" title="5.12 接口"></a>5.12 接口</h4><p>接口用于对复杂的数据结构进行类型描述。</p>
<p>先来观察一段 JavaScript 代码，看看代码中存在什么问题。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">getUserInfo</span>(<span class="hljs-params">user</span>) &#123;<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`<span class="hljs-subst">$&#123;user.name&#125;</span> - <span class="hljs-subst">$&#123;user.age&#125;</span>`</span>);<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 运行时错误: Uncaught TypeError: Cannot read properties of undefined (reading &#x27;name&#x27;)</span><br><span class="hljs-title function_">getUserInfo</span>();<br></code></pre></td></tr></table></figure>

<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// undefined - undefined</span><br><span class="hljs-title function_">getUserInfo</span>(<span class="hljs-string">&quot;张三&quot;</span>, <span class="hljs-number">20</span>);<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 张三 - undefined</span><br><span class="hljs-title function_">getUserInfo</span>(&#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">178</span> &#125;);<br></code></pre></td></tr></table></figure>

<p>JavaScript 是弱类型的语言，并不会对代码进行任何的检测。在 TypeScript 中，接口可以解决上述问题。</p>
<p>在 TypeScript 中，使用 interface 关键字定义接口，通过接口可以约束对象的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">User</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">getUserInfo</span>(<span class="hljs-params">user: User</span>) &#123;<br>  <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">$&#123;user.name&#125;</span> - <span class="hljs-subst">$&#123;user.age&#125;</span>`</span>;<br>&#125;<br><br><span class="hljs-title function_">getUserInfo</span>(&#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">20</span> &#125;);<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// TS2554: Expected 1 arguments, but got 0.</span><br><span class="hljs-title function_">getUserInfo</span>();<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// TS2345: Argument of type &#x27;string&#x27; is not assignable to parameter of type &#x27;User&#x27;.</span><br><span class="hljs-title function_">getUserInfo</span>(<span class="hljs-string">&quot;张三&quot;</span>);<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// TS2554: Expected 1 arguments, but got 2.</span><br><span class="hljs-title function_">getUserInfo</span>(<span class="hljs-string">&quot;张三&quot;</span>, <span class="hljs-number">20</span>);<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// TS2345: Argument of type &#x27;&#123; name: string; height: number; &#125;&#x27; is not assignable to parameter of type &#x27;User&#x27;.</span><br><span class="hljs-comment">// Object literal may only specify known properties, and &#x27;height&#x27; does not exist in type &#x27;User&#x27;.</span><br><span class="hljs-title function_">getUserInfo</span>(&#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">20</span> &#125;);<br></code></pre></td></tr></table></figure>

<p>接口中定义的规范都是必须被实现的，也就是说你定义的变量的值必须符合接口规范。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-attr">isMarray</span>: <span class="hljs-built_in">boolean</span>;<br>  <span class="hljs-title function_">summary</span>(): <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">printPerson</span>(<span class="hljs-params">person: Person</span>) &#123;<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(person);<br>&#125;<br><br><span class="hljs-keyword">const</span> person = &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>  <span class="hljs-attr">age</span>: <span class="hljs-number">20</span>,<br>  <span class="hljs-attr">isMarray</span>: <span class="hljs-literal">false</span>,<br>&#125;;<br><br><span class="hljs-comment">// 类型&quot;&#123; name: string; age: number; isMarray: boolean; &#125;&quot;的参数不能赋给类型&quot;Person&quot;的参数</span><br><span class="hljs-comment">// 类型&quot;&#123; name: string; age: number; isMarray: boolean; &#125;&quot;中缺少属性 &quot;summary&quot;, 但类型&quot;Person&quot;中需要该属性</span><br><span class="hljs-title function_">printPerson</span>(person);<br></code></pre></td></tr></table></figure>

<p>在实现了接口规范的情况下，规范以外的值默认是允许存在的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Reportable</span> &#123;<br>  <span class="hljs-title function_">summary</span>(): <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">printSummary</span>(<span class="hljs-params">item: Reportable</span>): <span class="hljs-built_in">void</span> &#123;<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(item.<span class="hljs-title function_">summary</span>());<br>&#125;<br><br><span class="hljs-keyword">const</span> person = &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>  <span class="hljs-title function_">summary</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-string">`您好, 我的名字叫<span class="hljs-subst">$&#123;<span class="hljs-variable language_">this</span>.name&#125;</span>`</span>;<br>  &#125;,<br>&#125;;<br><br><span class="hljs-keyword">const</span> drink = &#123;<br>  <span class="hljs-attr">color</span>: <span class="hljs-string">&quot;棕色&quot;</span>,<br>  <span class="hljs-title function_">summary</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;我喝的咖啡是$&#123;brow&#125;的&quot;</span>;<br>  &#125;,<br>&#125;;<br><br><span class="hljs-title function_">printSummary</span>(person);<br><span class="hljs-title function_">printSummary</span>(drink);<br></code></pre></td></tr></table></figure>

<p>接口具有继承特性，即接口与接口之间可以存在继承关系，而且一个接口可以继承多个接口。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 接口继承示例</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Sizes</span> &#123;<br>  <span class="hljs-attr">sizes</span>: <span class="hljs-built_in">string</span>[];<br>  <span class="hljs-title function_">getAvailableSizes</span>(): <span class="hljs-built_in">string</span>[];<br>&#125;<br><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Shape</span> &#123;<br>  <span class="hljs-attr">color</span>: <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Pizza</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Sizes</span>, <span class="hljs-title class_">Shape</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">pizza</span>: <span class="hljs-title class_">Pizza</span> = &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>  <span class="hljs-attr">color</span>: <span class="hljs-string">&quot;skyblue&quot;</span>,<br>  <span class="hljs-attr">sizes</span>: [<span class="hljs-string">&quot;large&quot;</span>, <span class="hljs-string">&quot;small&quot;</span>],<br>  <span class="hljs-title function_">getAvailableSizes</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">sizes</span>;<br>  &#125;,<br>&#125;;<br></code></pre></td></tr></table></figure>

<p>接口具有声明合并特性，即多个相同名称的接口会自动合并。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Box</span> &#123;<br>  <span class="hljs-attr">height</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-attr">width</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Box</span> &#123;<br>  <span class="hljs-attr">scale</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">box</span>: <span class="hljs-title class_">Box</span> = &#123; <span class="hljs-attr">height</span>: <span class="hljs-number">5</span>, <span class="hljs-attr">width</span>: <span class="hljs-number">6</span>, <span class="hljs-attr">scale</span>: <span class="hljs-number">10</span> &#125;;<br></code></pre></td></tr></table></figure>

<p>接口可以被类实现，实现了接口的类必须符合接口规范。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Calendar</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-title function_">addEvent</span>(): <span class="hljs-built_in">void</span>;<br>  <span class="hljs-title function_">removeEvent</span>(): <span class="hljs-built_in">void</span>;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">GoogleCalendar</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Calendar</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span> = <span class="hljs-string">&quot;test&quot;</span>;<br>  <span class="hljs-title function_">addEvent</span>(): <span class="hljs-built_in">void</span> &#123;&#125;<br>  <span class="hljs-title function_">removeEvent</span>(): <span class="hljs-built_in">void</span> &#123;&#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>使用接口可以约束函数的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Sum</span> &#123;<br>  (<span class="hljs-attr">n</span>: <span class="hljs-built_in">number</span>, <span class="hljs-attr">m</span>: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-keyword">const</span> <span class="hljs-attr">sum</span>: <span class="hljs-title class_">Sum</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">a, b</span>) &#123;<br>  <span class="hljs-keyword">return</span> a + b;<br>&#125;;<br></code></pre></td></tr></table></figure>

<h4 id="5-13-interface-与-type"><a href="#5-13-interface-与-type" class="headerlink" title="5.13 interface 与 type"></a>5.13 interface 与 type</h4><p>在 TypeScript 中，type 可以定义对象、联合类型、基本数据类型，而 interface 只能定义对象类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// ISBN: 国际标准书号</span><br><span class="hljs-keyword">type</span> <span class="hljs-variable constant_">ISBN</span> = <span class="hljs-built_in">number</span> | <span class="hljs-built_in">string</span>;<br><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">PublicationT</span> = &#123;<br>  <span class="hljs-attr">isbn</span>: <span class="hljs-variable constant_">ISBN</span>;<br>  <span class="hljs-attr">author</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">publisher</span>: <span class="hljs-built_in">string</span>;<br>&#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 接口只能定义对象类型</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">PublicationI</span> &#123;<br>  <span class="hljs-attr">isbn</span>: <span class="hljs-variable constant_">ISBN</span>;<br>  <span class="hljs-attr">author</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">publisher</span>: <span class="hljs-built_in">string</span>;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="6-其他类型"><a href="#6-其他类型" class="headerlink" title="6. 其他类型"></a>6. 其他类型</h3><h3 id="6-1-泛型"><a href="#6-1-泛型" class="headerlink" title="6.1 泛型"></a>6.1 泛型</h3><p>泛型是指将类型作为参数进行传递，通过参数传递类型解决代码复用问题 ( 代码中类型的复用问题，通过类型复用减少重复代码 )。</p>
<p>泛型传参和函数传参要解决的问题是一样的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">a</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> <span class="hljs-number">1</span> + <span class="hljs-number">1</span>;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">b</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> <span class="hljs-number">2</span> + <span class="hljs-number">2</span>;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">c</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> <span class="hljs-number">3</span> + <span class="hljs-number">3</span>;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">sum</span>(<span class="hljs-params">n: <span class="hljs-built_in">number</span>, m: <span class="hljs-built_in">number</span></span>) &#123;<br>  <span class="hljs-keyword">return</span> n + m;<br>&#125;<br><span class="hljs-title function_">sum</span>(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>);<br><span class="hljs-title function_">sum</span>(<span class="hljs-number">2</span>, <span class="hljs-number">2</span>);<br><span class="hljs-title function_">sum</span>(<span class="hljs-number">3</span>, <span class="hljs-number">3</span>);<br></code></pre></td></tr></table></figure>

<h4 id="1-泛型函数"><a href="#1-泛型函数" class="headerlink" title="1. 泛型函数"></a>1. 泛型函数</h4><p>目标：声明一个函数，接收一个参数，接收什么类型的参数就返回什么类型的参数。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">getValue</span>(<span class="hljs-params">value: <span class="hljs-built_in">any</span></span>): <span class="hljs-built_in">any</span> &#123;<br>  <span class="hljs-keyword">return</span> value;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">getString</span>(<span class="hljs-params">value: <span class="hljs-built_in">string</span></span>): <span class="hljs-built_in">string</span> &#123;<br>  <span class="hljs-keyword">return</span> value;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">getNumber</span>(<span class="hljs-params">value: <span class="hljs-built_in">number</span></span>): <span class="hljs-built_in">number</span> &#123;<br>  <span class="hljs-keyword">return</span> value;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> getValue&lt;T&gt;(<span class="hljs-attr">value</span>: T): T &#123;<br>  <span class="hljs-keyword">return</span> value;<br>&#125;<br><br>getValue&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">&quot;hello&quot;</span>);<br>getValue&lt;<span class="hljs-built_in">number</span>&gt;(<span class="hljs-number">100</span>);<br><br><span class="hljs-comment">// 泛型实参可以忽略 你传递的参数的类型就是要传递的泛型的类型</span><br><span class="hljs-title function_">echo</span>(<span class="hljs-string">&quot;hello&quot;</span>);<br></code></pre></td></tr></table></figure>

<h4 id="2-泛型类"><a href="#2-泛型类" class="headerlink" title="2. 泛型类"></a>2. 泛型类</h4><p>需求：通过类创建对象，对象的 key 属性可以是字符串可以是数值，对象的 value 属性可以是字符串可以是数值。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript">&#123;<span class="hljs-attr">key</span>: <span class="hljs-built_in">string</span>, <span class="hljs-attr">value</span>: <span class="hljs-built_in">string</span>&#125;<br>&#123;<span class="hljs-attr">key</span>: <span class="hljs-built_in">number</span>, <span class="hljs-attr">value</span>: <span class="hljs-built_in">number</span>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">StringKeyValuePair</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> key: <span class="hljs-built_in">string</span>, <span class="hljs-keyword">public</span> value: <span class="hljs-built_in">string</span></span>) &#123;&#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">NumberKeyValuePair</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> key: <span class="hljs-built_in">number</span>, <span class="hljs-keyword">public</span> value: <span class="hljs-built_in">number</span></span>) &#123;&#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">KeyValuePair</span>&lt;K, V&gt; &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> key: K, <span class="hljs-keyword">public</span> value: V</span>) &#123;&#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>需求：创建数组，数组中可以存储字符串也可以存储数值，通过索引可以获取到数组中的值。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">ArrayOfNumbers</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> collection: <span class="hljs-built_in">number</span>[]</span>) &#123;&#125;<br>  <span class="hljs-title function_">get</span>(index): <span class="hljs-built_in">number</span> &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">collection</span>[index];<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ArrayOfStrings</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> collection: <span class="hljs-built_in">string</span>[]</span>) &#123;&#125;<br>  <span class="hljs-title function_">get</span>(index): <span class="hljs-built_in">string</span> &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">collection</span>[index];<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>在以上代码中，数值数组类和字符串数组类所做的事情是一样的，但由于创建的数据类型不同，所以写成了两个类，它们属于重复代码。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">ArrayOfAnything</span>&lt;T&gt; &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> collection: T[]</span>) &#123;&#125;<br>  <span class="hljs-title function_">get</span>(index): T &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">collection</span>[index];<br>  &#125;<br>&#125;<br><span class="hljs-comment">// constructor ArrayOfAnything&lt;number&gt;(collection: number[]): ArrayOfAnything&lt;number&gt;</span><br><span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayOfAnything</span>&lt;<span class="hljs-built_in">number</span>&gt;([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);<br><span class="hljs-comment">// constructor ArrayOfAnything&lt;string&gt;(collection: string[]): ArrayOfAnything&lt;string&gt;</span><br><span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayOfAnything</span>&lt;<span class="hljs-built_in">string</span>&gt;([<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>, <span class="hljs-string">&quot;c&quot;</span>]);<br></code></pre></td></tr></table></figure>

<h4 id="3-泛型接口"><a href="#3-泛型接口" class="headerlink" title="3. 泛型接口"></a>3. 泛型接口</h4><p>需求：创建 fetch 方法用于获取数据，当获取用户数据时，fetch 方法的返回值类型为用户，当获取产品数据时， fetch 方法的返回值类型为产品，不论是用户数据还是产品数据都要被包含在响应对象中。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">MyResponse</span>&lt;T&gt; &#123;<br>  <span class="hljs-attr">data</span>: T | <span class="hljs-literal">null</span>;<br>&#125;<br><br><span class="hljs-keyword">function</span> fetch&lt;T&gt;(): <span class="hljs-title class_">MyResponse</span>&lt;T&gt; &#123;<br>  <span class="hljs-keyword">return</span> &#123; <span class="hljs-attr">data</span>: <span class="hljs-literal">null</span> &#125;;<br>&#125;<br><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">User</span> &#123;<br>  <span class="hljs-attr">username</span>: <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Product</span> &#123;<br>  <span class="hljs-attr">title</span>: <span class="hljs-built_in">string</span>;<br>&#125;<br><br>fetch&lt;<span class="hljs-title class_">User</span>&gt;().<span class="hljs-property">data</span>?.<span class="hljs-property">username</span>;<br>fetch&lt;<span class="hljs-title class_">Product</span>&gt;().<span class="hljs-property">data</span>?.<span class="hljs-property">title</span>;<br></code></pre></td></tr></table></figure>

<h4 id="4-泛型约束"><a href="#4-泛型约束" class="headerlink" title="4. 泛型约束"></a>4. 泛型约束</h4><p>泛型约束是指对泛型参数的范围进行约束，就是说虽然类型可以被当做参数传递，但是传递的类型不能是随意的想传什么就传什么，通过泛型约束可以限制能够传递的类型的范围。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 限制类型 T 的范围, 就是说 T 的类型要么是字符串要么是数值 其他的是不可以的</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">StringOrNumberArray</span>&lt;T <span class="hljs-keyword">extends</span> <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>&gt; &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> collection: T[]</span>) &#123;&#125;<br>  <span class="hljs-title function_">get</span>(<span class="hljs-attr">index</span>: <span class="hljs-built_in">number</span>): T &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">collection</span>[index];<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">new</span> <span class="hljs-title class_">StringOrNumberArray</span>&lt;<span class="hljs-built_in">string</span>&gt;([<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>]);<br><span class="hljs-keyword">new</span> <span class="hljs-title class_">StringOrNumberArray</span>&lt;<span class="hljs-built_in">number</span>&gt;([<span class="hljs-number">100</span>, <span class="hljs-number">200</span>]);<br><span class="hljs-comment">// 类型&quot;boolean&quot;不满足约束&quot;string | number&quot;</span><br><span class="hljs-comment">// new StringOrNumberArray&lt;boolean&gt;([true, false]);</span><br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> echo&lt;T <span class="hljs-keyword">extends</span> <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>&gt;(<span class="hljs-attr">value</span>: T): T &#123;<br>  <span class="hljs-keyword">return</span> value;<br>&#125;<br>echo&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">&quot;Hello&quot;</span>); <span class="hljs-comment">// ✅</span><br>echo&lt;<span class="hljs-built_in">number</span>&gt;(<span class="hljs-number">100</span>); <span class="hljs-comment">// ✅</span><br>echo&lt;<span class="hljs-built_in">boolean</span>&gt;(<span class="hljs-literal">true</span>); <span class="hljs-comment">// ❎ 类型&quot;boolean&quot;不满足约束&quot;string | number&quot;. ts(2344)</span><br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">function</span> echo&lt;T <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Person</span>&gt;(<span class="hljs-attr">value</span>: T): T &#123;<br>  <span class="hljs-keyword">return</span> value;<br>&#125;<br><br>echo&lt;<span class="hljs-title class_">Person</span>&gt;(&#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span> &#125;); <span class="hljs-comment">// ✅</span><br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> &#123;<br>  <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> name: <span class="hljs-built_in">string</span></span>) &#123;&#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Custom</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Person</span> &#123;&#125;<br><br><span class="hljs-keyword">function</span> echo&lt;T <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Person</span>&gt;(<span class="hljs-attr">value</span>: T): T &#123;<br>  <span class="hljs-keyword">return</span> value;<br>&#125;<br><br>echo&lt;<span class="hljs-title class_">Person</span>&gt;(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">&quot;张三&quot;</span>));<br>echo&lt;<span class="hljs-title class_">Custom</span>&gt;(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Custom</span>(<span class="hljs-string">&quot;李四&quot;</span>));<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Printable</span> &#123;<br>  <span class="hljs-title function_">print</span>(): <span class="hljs-built_in">void</span>;<br>&#125;<br><br><span class="hljs-keyword">function</span> echo&lt;T <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Printable</span>&gt;(<span class="hljs-attr">target</span>: T) &#123;<br>  target.<span class="hljs-title function_">print</span>();<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Car</span> &#123;<br>  <span class="hljs-title function_">print</span>(<span class="hljs-params"></span>) &#123;&#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Hourse</span> &#123;<br>  <span class="hljs-title function_">print</span>(<span class="hljs-params"></span>) &#123;&#125;<br>&#125;<br><br>echo&lt;<span class="hljs-title class_">Car</span>&gt;(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Car</span>());<br>echo&lt;<span class="hljs-title class_">Hourse</span>&gt;(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Hourse</span>());<br></code></pre></td></tr></table></figure>

<h4 id="5-继承泛型类"><a href="#5-继承泛型类" class="headerlink" title="5. 继承泛型类"></a>5. 继承泛型类</h4><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Store</span>&lt;T&gt; &#123;<br>  <span class="hljs-keyword">protected</span> <span class="hljs-attr">_objects</span>: T[] = [];<br><br>  <span class="hljs-title function_">add</span>(<span class="hljs-params">obj: T</span>) &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">_objects</span>.<span class="hljs-title function_">push</span>(obj);<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Product</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">price</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-keyword">const</span> store = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Store</span>&lt;<span class="hljs-title class_">Product</span>&gt;();<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">CompressibleStore</span>&lt;T&gt; <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Store</span>&lt;T&gt; &#123;&#125;<br><span class="hljs-keyword">new</span> <span class="hljs-title class_">CompressibleStore</span>&lt;<span class="hljs-title class_">Product</span>&gt;();<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">ProductStore</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Store</span>&lt;<span class="hljs-title class_">Product</span>&gt; &#123;&#125;<br></code></pre></td></tr></table></figure>

<h4 id="6-2-keyof-操作符"><a href="#6-2-keyof-操作符" class="headerlink" title="6.2 keyof 操作符"></a>6.2 keyof 操作符</h4><p>keyof 是类型运算符，接收类型返回类型，返回的是接收类型的属性字面量联合类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Product</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">price</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-comment">// 属性字面量联合类型 name | price</span><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">ProductKeys</span> = keyof <span class="hljs-title class_">Product</span>;<br><br><span class="hljs-keyword">const</span> <span class="hljs-attr">keys1</span>: <span class="hljs-title class_">ProductKeys</span> = <span class="hljs-string">&quot;price&quot;</span>;<br><span class="hljs-keyword">const</span> <span class="hljs-attr">keys2</span>: <span class="hljs-title class_">ProductKeys</span> = <span class="hljs-string">&quot;name&quot;</span>;<br><span class="hljs-comment">// 不能将类型&quot;a&quot;分配给类型“keyof Product”。</span><br><span class="hljs-comment">// const keys3: ProductKeys = &quot;a&quot;;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Store</span>&lt;T&gt; &#123;<br>  <span class="hljs-keyword">protected</span> <span class="hljs-attr">_objects</span>: T[] = [];<br><br>  <span class="hljs-title function_">add</span>(<span class="hljs-params">obj: T</span>) &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-property">_objects</span>.<span class="hljs-title function_">push</span>(obj);<br>  &#125;<br><br>  <span class="hljs-title function_">find</span>(<span class="hljs-attr">property</span>: keyof T, <span class="hljs-attr">value</span>: <span class="hljs-built_in">unknown</span>): T | <span class="hljs-literal">undefined</span> &#123;<br>    <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_objects</span>.<span class="hljs-title function_">find</span>(<span class="hljs-function">(<span class="hljs-params">obj</span>) =&gt;</span> obj[property] === value);<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Product</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">price</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-keyword">const</span> store = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Store</span>&lt;<span class="hljs-title class_">Product</span>&gt;();<br>store.<span class="hljs-title function_">add</span>(&#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;Hello&quot;</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">100</span> &#125;);<br>store.<span class="hljs-title function_">find</span>(<span class="hljs-string">&quot;name&quot;</span>, <span class="hljs-string">&quot;Hello&quot;</span>);<br>store.<span class="hljs-title function_">find</span>(<span class="hljs-string">&quot;price&quot;</span>, <span class="hljs-number">100</span>);<br><span class="hljs-comment">// TS2345: Argument of type &#x27;&quot;a&quot;&#x27; is not assignable to parameter of type &#x27;keyof Product&#x27;.</span><br>store.<span class="hljs-title function_">find</span>(<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-number">12</span>);<br><span class="hljs-comment">// TS2345: Argument of type &#x27;&quot;greet&quot;&#x27; is not assignable to parameter of type &#x27;keyof Product&#x27;.</span><br>store.<span class="hljs-title function_">find</span>(<span class="hljs-string">&quot;greet&quot;</span>, <span class="hljs-string">&quot;hi&quot;</span>);<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 多学一招: 获取类型中某一个属性值的类型</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Product</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">price</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><span class="hljs-comment">// type nameType = string</span><br><span class="hljs-keyword">type</span> nameType = <span class="hljs-title class_">Product</span>[<span class="hljs-string">&quot;name&quot;</span>];<br><span class="hljs-comment">// type nameType = number</span><br><span class="hljs-keyword">type</span> priceType = <span class="hljs-title class_">Product</span>[<span class="hljs-string">&quot;price&quot;</span>];<br></code></pre></td></tr></table></figure>

<h4 id="6-3-typeof-操作符"><a href="#6-3-typeof-操作符" class="headerlink" title="6.3 typeof 操作符"></a>6.3 typeof 操作符</h4><p>TypeScript 在语言层面又添加了一个新的 typeof 运算符，该运算符可以用来获取一个变量的类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">const</span> person = &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>  <span class="hljs-attr">age</span>: <span class="hljs-number">20</span>,<br>&#125;;<br><span class="hljs-keyword">type</span> <span class="hljs-title class_">Person</span> = <span class="hljs-keyword">typeof</span> person;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>&#125;<br><br><span class="hljs-keyword">type</span> r = <span class="hljs-title class_">ReturnType</span>&lt;<span class="hljs-keyword">typeof</span> fn&gt;;<br></code></pre></td></tr></table></figure>

<h4 id="6-4-映射类型"><a href="#6-4-映射类型" class="headerlink" title="6.4 映射类型"></a>6.4 映射类型</h4><p>映射类型是指基于现有类型产生新的类型。</p>
<p>通过遍历语法拷贝原有类型，再在拷贝类型的基础上进行修改从而产生新的类型。</p>
<p>如何拷贝原有类型？拷贝原有类型主要拷贝的是两部分，原有类型中有哪些属性、属性的值是什么类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Product</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">price</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">NProduct</span> = &#123;<br>  <span class="hljs-comment">// 1. 如何拷贝原有类型中的属性?</span><br>  <span class="hljs-comment">// keyof Product =&gt; name | price</span><br>  <span class="hljs-comment">// K in (name | price)</span><br>  <span class="hljs-comment">// name</span><br>  <span class="hljs-comment">// price</span><br><br>  <span class="hljs-comment">// 2.如何获取属性(name, price)值原有的类型</span><br>  <span class="hljs-comment">// 类型[属性名称] 得到的结果就是属性值的类型</span><br>  <span class="hljs-comment">// Product[K] =&gt; Product[name] =&gt; string</span><br>  <span class="hljs-comment">// Product[K] =&gt; Product[price] =&gt; number</span><br>  [k <span class="hljs-keyword">in</span> keyof <span class="hljs-title class_">Product</span>]: <span class="hljs-title class_">Product</span>[k];<br>&#125;;<br></code></pre></td></tr></table></figure>

<p>目标：基于 Product 类型，创建新类型，新类型中的属性都是只读的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 最终目标如下</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Product</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">price</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">ReadOnlyProduct</span> = &#123;<br>  <span class="hljs-keyword">readonly</span> <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-keyword">readonly</span> <span class="hljs-attr">price</span>: <span class="hljs-built_in">number</span>;<br>&#125;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">ReadOnlyProduct</span> = &#123;<br>  <span class="hljs-keyword">readonly</span> [K <span class="hljs-keyword">in</span> keyof <span class="hljs-title class_">Product</span>]: <span class="hljs-title class_">Product</span>[K];<br>&#125;;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">product</span>: <span class="hljs-title class_">ReadOnlyProduct</span> = &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;test&quot;</span>,<br>  <span class="hljs-attr">price</span>: <span class="hljs-number">100</span>,<br>&#125;;<br><br><span class="hljs-comment">// TS2540: Cannot assign to &#x27;name&#x27; because it is a read-only property.</span><br>product.<span class="hljs-property">name</span> = <span class="hljs-string">&quot;hello&quot;</span>;<br></code></pre></td></tr></table></figure>

<p>目标：创建 MyReadOnly 类型，通过泛型参数接收旧的类型，返回新类型，新类型中的属性都是只读的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">MyReadOnly</span>&lt;T&gt; = &#123;<br>  <span class="hljs-keyword">readonly</span> [K <span class="hljs-keyword">in</span> keyof T]: T[K];<br>&#125;;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">product</span>: <span class="hljs-title class_">MyReadOnly</span>&lt;<span class="hljs-title class_">Product</span>&gt; = &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;test&quot;</span>,<br>  <span class="hljs-attr">price</span>: <span class="hljs-number">100</span>,<br>&#125;;<br><br><span class="hljs-comment">// TS2540: Cannot assign to &#x27;name&#x27; because it is a read-only property.</span><br>product.<span class="hljs-property">name</span> = <span class="hljs-string">&quot;hello&quot;</span>;<br></code></pre></td></tr></table></figure>

<p>目标：创建 MyOptional 类型，通过泛型参数接收旧的类型，返回新类型，新类型中的属性都是可选的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">MyOptional</span>&lt;T&gt; = &#123;<br>  [K <span class="hljs-keyword">in</span> keyof T]?: T[K];<br>&#125;;<br></code></pre></td></tr></table></figure>

<p>目标：创建 MyNullable 类型，通过泛型参数接收旧的类型，返回新类型，新类型中的属性都是可以为 null 的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">type</span> <span class="hljs-title class_">MyNullable</span>&lt;T&gt; = &#123;<br>  [K <span class="hljs-keyword">in</span> keyof T]: T[K] | <span class="hljs-literal">null</span>;<br>&#125;;<br></code></pre></td></tr></table></figure>

<p>目标：创建 MyWritable 类型，通过泛型参数接收旧的类型，返回新类型，新类型中的属性都是可写的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">User</span> &#123;<br>  <span class="hljs-keyword">readonly</span> <span class="hljs-attr">username</span>: <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">MyWritable</span>&lt;T&gt; = &#123;<br>  -<span class="hljs-keyword">readonly</span> [K <span class="hljs-keyword">in</span> keyof T]: T[K];<br>&#125;;<br><br><span class="hljs-keyword">const</span> <span class="hljs-attr">userCanWrite</span>: <span class="hljs-title class_">MyWritable</span>&lt;<span class="hljs-title class_">User</span>&gt; = &#123;<br>  <span class="hljs-attr">username</span>: <span class="hljs-string">&quot;李四&quot;</span>,<br>&#125;;<br><br>userCanWrite.<span class="hljs-property">username</span> = <span class="hljs-string">&quot;王五&quot;</span>;<br></code></pre></td></tr></table></figure>

<p>目标：创建 MyNecessary 类型，通过泛型参数接收旧的类型，返回新类型，新类型中的属性都是必选的。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">User</span> &#123;<br>  username?: <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">MyNecessary</span>&lt;T&gt; = &#123;<br>  [K <span class="hljs-keyword">in</span> keyof T]-?: T[K];<br>&#125;;<br><br><span class="hljs-comment">// 类型 &quot;&#123;&#125;&quot; 中缺少属性 &quot;username&quot;, 但类型 &quot;Necessary&lt;User&gt;&quot; 中需要该属性</span><br><span class="hljs-keyword">const</span> <span class="hljs-attr">user</span>: <span class="hljs-title class_">MyNecessary</span>&lt;<span class="hljs-title class_">User</span>&gt; = &#123;&#125;;<br></code></pre></td></tr></table></figure>

<h4 id="6-5-工具类型"><a href="#6-5-工具类型" class="headerlink" title="6.5 工具类型"></a>6.5 工具类型</h4><h4 id="6-5-1-Partical"><a href="#6-5-1-Partical" class="headerlink" title="6.5.1 Partical"></a>6.5.1 Partical</h4><p>将类型中的属性都变成可选的，接收类型，返回类型。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ty">Partial&lt;Type&gt;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-keyword">type</span> anothor = <span class="hljs-title class_">Partical</span>&lt;<span class="hljs-title class_">Person</span>&gt;;<br><span class="hljs-comment">// &#123;name?: string, age?: number&#125;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">function</span> updateObject&lt;T&gt;(<span class="hljs-attr">obj</span>: T, <span class="hljs-attr">props</span>: <span class="hljs-title class_">Partial</span>&lt;T&gt;) &#123;<br>  <span class="hljs-keyword">return</span> &#123; ...obj, ...props &#125;;<br>&#125;<br><br>updateObject&lt;<span class="hljs-title class_">Person</span>&gt;(person, &#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;李四&quot;</span> &#125;);<br></code></pre></td></tr></table></figure>

<h4 id="6-5-2-Readonly"><a href="#6-5-2-Readonly" class="headerlink" title="6.5.2 Readonly"></a>6.5.2 Readonly</h4><p>将类型中的属性都变成只读的，接收类型，返回类型。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-title class_">Readonly</span>&lt;<span class="hljs-title class_">Type</span>&gt;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-comment">// &#123;readonly name: string, readonly age: number&#125;</span><br><span class="hljs-keyword">const</span> <span class="hljs-attr">anthor</span>: <span class="hljs-title class_">Readonly</span>&lt;<span class="hljs-title class_">Person</span>&gt; = &#123;<br>  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;李四&quot;</span>,<br>  <span class="hljs-attr">age</span>: <span class="hljs-number">40</span>,<br>&#125;;<br><br><span class="hljs-comment">// 不可以修改</span><br><span class="hljs-comment">// anthor.name = &quot;赵六&quot;;</span><br></code></pre></td></tr></table></figure>

<h4 id="6-5-3-Record"><a href="#6-5-3-Record" class="headerlink" title="6.5.3 Record"></a>6.5.3 Record</h4><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-title class_">Record</span>&lt;<span class="hljs-title class_">Keys</span>, <span class="hljs-title class_">Type</span>&gt;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">EmployeeType</span> &#123;<br>  <span class="hljs-attr">id</span>: <span class="hljs-built_in">number</span>;<br>  <span class="hljs-attr">fullname</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">role</span>: <span class="hljs-built_in">string</span>;<br>&#125;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">employees</span>: <span class="hljs-title class_">Record</span>&lt;<span class="hljs-built_in">number</span>, <span class="hljs-title class_">EmployeeType</span>&gt; = &#123;<br>  <span class="hljs-number">1</span>: &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">fullname</span>: <span class="hljs-string">&quot;John Doe&quot;</span>, <span class="hljs-attr">role</span>: <span class="hljs-string">&quot;Designer&quot;</span> &#125;,<br>  <span class="hljs-number">2</span>: &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">fullname</span>: <span class="hljs-string">&quot;Ibrahima Fall&quot;</span>, <span class="hljs-attr">role</span>: <span class="hljs-string">&quot;Developer&quot;</span> &#125;,<br>  <span class="hljs-number">3</span>: &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">fullname</span>: <span class="hljs-string">&quot;Sara Duckson&quot;</span>, <span class="hljs-attr">role</span>: <span class="hljs-string">&quot;Developer&quot;</span> &#125;,<br>&#125;;<br></code></pre></td></tr></table></figure>

<h4 id="6-5-4-Omit"><a href="#6-5-4-Omit" class="headerlink" title="6.5.4 Omit"></a>6.5.4 Omit</h4><p>接收类型，得到新类型，在新类型中不要包含 keys</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-title class_">Omit</span>&lt;<span class="hljs-title class_">Type</span>, <span class="hljs-title class_">Keys</span>&gt;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Todo</span> &#123;<br>  <span class="hljs-attr">title</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">description</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">completed</span>: <span class="hljs-built_in">boolean</span>;<br>  <span class="hljs-attr">createdAt</span>: <span class="hljs-built_in">number</span>;<br>&#125;<br><br><span class="hljs-comment">/*</span><br><span class="hljs-comment">  type TodoPreview = &#123;</span><br><span class="hljs-comment">    completed: boolean;</span><br><span class="hljs-comment">    createdAt: number;</span><br><span class="hljs-comment">  &#125;</span><br><span class="hljs-comment">*/</span><br><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">TodoPreview</span> = <span class="hljs-title class_">Omit</span>&lt;<span class="hljs-title class_">Todo</span>, <span class="hljs-string">&quot;description&quot;</span> | <span class="hljs-string">&quot;title&quot;</span>&gt;;<br></code></pre></td></tr></table></figure>

<h4 id="6-5-5-Pick"><a href="#6-5-5-Pick" class="headerlink" title="6.5.5 Pick"></a>6.5.5 Pick</h4><p>接收类型，返回新类型，在新类型中要包含 keys</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-title class_">Pick</span>&lt;<span class="hljs-title class_">Type</span>, <span class="hljs-title class_">Keys</span>&gt;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Todo</span> &#123;<br>  <span class="hljs-attr">title</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">description</span>: <span class="hljs-built_in">string</span>;<br>  <span class="hljs-attr">completed</span>: <span class="hljs-built_in">boolean</span>;<br>&#125;<br><br><span class="hljs-comment">/*</span><br><span class="hljs-comment">  type TodoPreview = &#123;</span><br><span class="hljs-comment">    title: string;</span><br><span class="hljs-comment">    completed: boolean;</span><br><span class="hljs-comment">  &#125;</span><br><span class="hljs-comment">*/</span><br><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">TodoPreview</span> = <span class="hljs-title class_">Pick</span>&lt;<span class="hljs-title class_">Todo</span>, <span class="hljs-string">&quot;title&quot;</span> | <span class="hljs-string">&quot;completed&quot;</span>&gt;;<br></code></pre></td></tr></table></figure>

<h4 id="6-5-6-Exclude"><a href="#6-5-6-Exclude" class="headerlink" title="6.5.6 Exclude"></a>6.5.6 Exclude</h4><p>接收联合类型，得到新类型，在新类型中排除联合类型中的 ExcludedMembers。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-title class_">Exclude</span>&lt;<span class="hljs-title class_">UnionType</span>, <span class="hljs-title class_">ExcludedMembers</span>&gt;;<br></code></pre></td></tr></table></figure>

<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// type T0 = &quot;b&quot; | &quot;c&quot;</span><br><span class="hljs-keyword">type</span> <span class="hljs-variable constant_">T0</span> = <span class="hljs-title class_">Exclude</span>&lt;<span class="hljs-string">&quot;a&quot;</span> | <span class="hljs-string">&quot;b&quot;</span> | <span class="hljs-string">&quot;c&quot;</span>, <span class="hljs-string">&quot;a&quot;</span>&gt;;<br><span class="hljs-comment">// type T1 = &quot;c&quot;</span><br><span class="hljs-keyword">type</span> <span class="hljs-variable constant_">T1</span> = <span class="hljs-title class_">Exclude</span>&lt;<span class="hljs-string">&quot;a&quot;</span> | <span class="hljs-string">&quot;b&quot;</span> | <span class="hljs-string">&quot;c&quot;</span>, <span class="hljs-string">&quot;a&quot;</span> | <span class="hljs-string">&quot;b&quot;</span>&gt;;<br></code></pre></td></tr></table></figure>

<h4 id="6-6-is"><a href="#6-6-is" class="headerlink" title="6.6 is"></a>6.6 is</h4><p>is 用于加强 TypeScript 类型推断，可以缩小类型的范围。</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// isString 函数的返回值为布尔类型</span><br><span class="hljs-comment">// 如果 isString 函数的返回值为 true, TypeScript 编译器就认定 s 是字符串类型</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">isString</span>(<span class="hljs-params">s: <span class="hljs-built_in">any</span></span>): s is <span class="hljs-built_in">string</span> &#123;<br>  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> s === <span class="hljs-string">&quot;string&quot;</span>;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">toUpperCase</span>(<span class="hljs-params">x: <span class="hljs-built_in">any</span></span>) &#123;<br>  <span class="hljs-keyword">if</span> (<span class="hljs-title function_">isString</span>(x)) &#123;<br>    <span class="hljs-keyword">return</span> x.<span class="hljs-title function_">toUpperCase</span>();<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>TypeScript</div>
      <div>http://example.com/2023/06/25/TypeScript/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>John Doe</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2023年6月25日</div>
        </div>
      
      
      
        <div class="license-meta-item">
          <div>许可协议</div>
          <div>
            
              
              
                <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
                  <span class="hint--top hint--rounded" aria-label="BY - 署名">
                    <i class="iconfont icon-by"></i>
                  </span>
                </a>
              
            
          </div>
        </div>
      
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2023/06/12/js/" title="js">
                        <span class="hidden-mobile">js</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header">
    <i class="iconfont icon-list"></i>
    <span>目录</span>
  </p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
    </div>
  
  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init(Object.assign({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      scrollSmooth    : true,
      includeTitleTags: true,
      headingsOffset  : -boardTop,
    }, CONFIG.toc));
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }

    Fluid.events.registerRefreshCallback(function() {
      if ('tocbot' in window) {
        tocbot.refresh();
        var toc = jQuery('#toc');
        if (toc.length === 0 || !tocbot) {
          return;
        }
        if (toc.find('.toc-list-item').length > 0) {
          toc.css('visibility', 'visible');
        }
      }
    });
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.11/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));

    Fluid.events.registerRefreshCallback(function() {
      if ('anchors' in window) {
        anchors.removeAll();
        var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
        var res = [];
        for (var item of el) {
          res.push('.markdown-body > ' + item.trim());
        }
        if (CONFIG.anchorjs.placement === 'left') {
          anchors.options.class = 'anchorjs-link-left';
        }
        anchors.add(res.join(', '));
      }
    });
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/js/local-search.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
